summaryrefslogtreecommitdiff
path: root/sql/ha_myisam.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_myisam.cc')
-rw-r--r--sql/ha_myisam.cc198
1 files changed, 146 insertions, 52 deletions
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 128cc191434..40081c975c8 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -27,10 +27,12 @@
#ifndef MASTER
#include "../srclib/myisam/myisamdef.h"
#else
-#include "../myisam/myisamdef.h"
-#include "../myisam/rt_index.h"
+#include "../storage/myisam/myisamdef.h"
+#include "../storage/myisam/rt_index.h"
#endif
+#include <mysql/plugin.h>
+
ulong myisam_recover_options= HA_RECOVER_NONE;
/* bits in myisam_recover_options */
@@ -50,12 +52,19 @@ TYPELIB myisam_stats_method_typelib= {
** MyISAM tables
*****************************************************************************/
+static handler *myisam_create_handler(TABLE_SHARE *table);
+
/* MyISAM handlerton */
+static const char myisam_hton_name[]= "MyISAM";
+static const char myisam_hton_comment[]=
+ "Default engine as of MySQL 3.23 with great performance";
+
handlerton myisam_hton= {
- "MyISAM",
+ MYSQL_HANDLERTON_INTERFACE_VERSION,
+ myisam_hton_name,
SHOW_OPTION_YES,
- "Default engine as of MySQL 3.23 with great performance",
+ myisam_hton_comment,
DB_TYPE_MYISAM,
NULL,
0, /* slot */
@@ -77,9 +86,29 @@ handlerton myisam_hton= {
MyISAM doesn't support transactions and doesn't have
transaction-dependent context: cursors can survive a commit.
*/
- HTON_CAN_RECREATE
+ myisam_create_handler, /* Create a new handler */
+ NULL, /* Drop a database */
+ mi_panic,/* Panic call */
+ NULL, /* Start Consistent Snapshot */
+ NULL, /* Flush logs */
+ NULL, /* Show status */
+ NULL, /* Partition flags */
+ NULL, /* Alter table flags */
+ NULL, /* Alter Tablespace */
+ NULL, /* Fill Files Table */
+ HTON_CAN_RECREATE,
+ NULL, /* binlog_func */
+ NULL, /* binlog_log_query */
+ NULL /* release_temporary_latches */
};
+
+static handler *myisam_create_handler(TABLE_SHARE *table)
+{
+ return new ha_myisam(table);
+}
+
+
// collect errors printed by mi_check routines
static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
@@ -160,7 +189,7 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
}
-ha_myisam::ha_myisam(TABLE *table_arg)
+ha_myisam::ha_myisam(TABLE_SHARE *table_arg)
:handler(&myisam_hton, table_arg), file(0),
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
HA_DUPP_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
@@ -277,15 +306,42 @@ err:
}
#endif /* HAVE_REPLICATION */
+
+bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
+ ulong type, TABLE *table,
+ uint count,
+ bool called_by_logger_thread)
+{
+ /*
+ To be able to open and lock for reading system tables like 'mysql.proc',
+ when we already have some tables opened and locked, and avoid deadlocks
+ we have to disallow write-locking of these tables with any other tables.
+ */
+ if (table->s->system_table &&
+ table->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE &&
+ count != 1)
+ {
+ my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table->s->db.str,
+ table->s->table_name.str);
+ return FALSE;
+ }
+ return TRUE;
+}
+
/* Name is here without an extension */
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
- if (!(file=mi_open(name, mode, test_if_locked)))
+ uint i;
+ if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
return (my_errno ? my_errno : -1);
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
+
+ if (!(test_if_locked & HA_OPEN_TMP_TABLE) && opt_myisam_use_mmap)
+ VOID(mi_extra(file, HA_EXTRA_MMAP, 0));
+
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
@@ -293,6 +349,15 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
int_table_flags|=HA_REC_NOT_IN_SEQ;
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
int_table_flags|=HA_HAS_CHECKSUM;
+
+ for (i= 0; i < table->s->keys; i++)
+ {
+ struct st_plugin_int *parser= table->key_info[i].parser;
+ if (table->key_info[i].flags & HA_USES_PARSER)
+ file->s->keyinfo[i].parser=
+ (struct st_mysql_ftparser *)parser->plugin->info;
+ table->key_info[i].block_size= file->s->keyinfo[i].block_length;
+ }
return (0);
}
@@ -332,7 +397,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
myisamchk_init(&param);
param.thd = thd;
param.op_name = "check";
- param.db_name= table->s->db;
+ param.db_name= table->s->db.str;
param.table_name= table->alias;
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
@@ -422,7 +487,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt)
myisamchk_init(&param);
param.thd = thd;
param.op_name= "analyze";
- param.db_name= table->s->db;
+ param.db_name= table->s->db.str;
param.table_name= table->alias;
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
@@ -450,7 +515,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
HA_CHECK_OPT tmp_check_opt;
char *backup_dir= thd->lex->backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- const char *table_name= table->s->table_name;
+ const char *table_name= table->s->table_name.str;
int error;
const char* errmsg;
DBUG_ENTER("restore");
@@ -459,8 +524,8 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
MI_NAME_DEXT))
DBUG_RETURN(HA_ADMIN_INVALID);
- if (my_copy(src_path, fn_format(dst_path, table->s->path, "",
- MI_NAME_DEXT, 4), MYF(MY_WME)))
+ strxmov(dst_path, table->s->normalized_path.str, MI_NAME_DEXT, NullS);
+ if (my_copy(src_path, dst_path, MYF(MY_WME)))
{
error= HA_ADMIN_FAILED;
errmsg= "Failed in my_copy (Error %d)";
@@ -477,8 +542,8 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
myisamchk_init(&param);
param.thd= thd;
param.op_name= "restore";
- param.db_name= table->s->db;
- param.table_name= table->s->table_name;
+ param.db_name= table->s->db.str;
+ param.table_name= table->s->table_name.str;
param.testflag= 0;
mi_check_print_error(&param, errmsg, my_errno);
DBUG_RETURN(error);
@@ -490,7 +555,7 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
{
char *backup_dir= thd->lex->backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- const char *table_name= table->s->table_name;
+ const char *table_name= table->s->table_name.str;
int error;
const char *errmsg;
DBUG_ENTER("ha_myisam::backup");
@@ -503,9 +568,8 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
goto err;
}
- if (my_copy(fn_format(src_path, table->s->path, "", reg_ext,
- MY_UNPACK_FILENAME),
- dst_path,
+ strxmov(src_path, table->s->normalized_path.str, reg_ext, NullS);
+ if (my_copy(src_path, dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE)))
{
error = HA_ADMIN_FAILED;
@@ -514,17 +578,16 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
}
/* Change extension */
- if (!fn_format(dst_path, dst_path, "", MI_NAME_DEXT,
- MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH))
+ if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir,
+ MI_NAME_DEXT))
{
errmsg = "Failed in fn_format() for .MYD file (errno: %d)";
error = HA_ADMIN_INVALID;
goto err;
}
- if (my_copy(fn_format(src_path, table->s->path, "", MI_NAME_DEXT,
- MY_UNPACK_FILENAME),
- dst_path,
+ strxmov(src_path, table->s->normalized_path.str, MI_NAME_DEXT, NullS);
+ if (my_copy(src_path, dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE)))
{
errmsg = "Failed copying .MYD file (errno: %d)";
@@ -539,8 +602,8 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
myisamchk_init(&param);
param.thd= thd;
param.op_name= "backup";
- param.db_name= table->s->db;
- param.table_name= table->s->table_name;
+ param.db_name= table->s->db.str;
+ param.table_name= table->s->table_name.str;
param.testflag = 0;
mi_check_print_error(&param,errmsg, my_errno);
DBUG_RETURN(error);
@@ -631,7 +694,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
ha_rows rows= file->state->records;
DBUG_ENTER("ha_myisam::repair");
- param.db_name= table->s->db;
+ param.db_name= table->s->db.str;
param.table_name= table->alias;
param.tmpfile_createflag = O_RDWR | O_TRUNC;
param.using_global_keycache = 1;
@@ -802,8 +865,8 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
myisamchk_init(&param);
param.thd= thd;
param.op_name= "assign_to_keycache";
- param.db_name= table->s->db;
- param.table_name= table->s->table_name;
+ param.db_name= table->s->db.str;
+ param.table_name= table->s->table_name.str;
param.testflag= 0;
mi_check_print_error(&param, errmsg);
}
@@ -870,8 +933,8 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
myisamchk_init(&param);
param.thd= thd;
param.op_name= "preload_keys";
- param.db_name= table->s->db;
- param.table_name= table->s->table_name;
+ param.db_name= table->s->db.str;
+ param.table_name= table->s->table_name.str;
param.testflag= 0;
mi_check_print_error(&param, errmsg);
DBUG_RETURN(error);
@@ -1125,8 +1188,8 @@ bool ha_myisam::check_and_repair(THD *thd)
old_query= thd->query;
old_query_length= thd->query_length;
pthread_mutex_lock(&LOCK_thread_count);
- thd->query= (char*) table->s->table_name;
- thd->query_length= (uint32) strlen(table->s->table_name);
+ thd->query= table->s->table_name.str;
+ thd->query_length= table->s->table_name.length;
pthread_mutex_unlock(&LOCK_thread_count);
if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
@@ -1312,7 +1375,11 @@ void ha_myisam::info(uint flag)
sortkey= info.sortkey;
ref_length= info.reflength;
share->db_options_in_use= info.options;
- block_size= myisam_block_size;
+ block_size= myisam_block_size; /* record block size */
+
+ /* Update share */
+ if (share->tmp_table == NO_TMP_TABLE)
+ pthread_mutex_lock(&share->mutex);
share->keys_in_use.set_prefix(share->keys);
share->keys_in_use.intersect_extended(info.key_map);
share->keys_for_keyread.intersect(share->keys_in_use);
@@ -1321,19 +1388,18 @@ void ha_myisam::info(uint flag)
memcpy((char*) table->key_info[0].rec_per_key,
(char*) info.rec_per_key,
sizeof(table->key_info[0].rec_per_key)*share->key_parts);
- raid_type= info.raid_type;
- raid_chunks= info.raid_chunks;
- raid_chunksize= info.raid_chunksize;
+ if (share->tmp_table == NO_TMP_TABLE)
+ pthread_mutex_unlock(&share->mutex);
/*
Set data_file_name and index_file_name to point at the symlink value
if table is symlinked (Ie; Real name is not same as generated name)
*/
- data_file_name=index_file_name=0;
- fn_format(name_buff, file->filename, "", MI_NAME_DEXT, 2);
+ data_file_name= index_file_name= 0;
+ fn_format(name_buff, file->filename, "", MI_NAME_DEXT, MY_APPEND_EXT);
if (strcmp(name_buff, info.data_file_name))
data_file_name=info.data_file_name;
- strmov(fn_ext(name_buff),MI_NAME_IEXT);
+ fn_format(name_buff, file->filename, "", MI_NAME_IEXT, MY_APPEND_EXT);
if (strcmp(name_buff, info.index_file_name))
index_file_name=info.index_file_name;
}
@@ -1401,12 +1467,6 @@ void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
{
create_info->auto_increment_value=auto_increment_value;
}
- if (!(create_info->used_fields & HA_CREATE_USED_RAID))
- {
- create_info->raid_type= raid_type;
- create_info->raid_chunks= raid_chunks;
- create_info->raid_chunksize= raid_chunksize;
- }
create_info->data_file_name=data_file_name;
create_info->index_file_name=index_file_name;
}
@@ -1424,7 +1484,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
MI_KEYDEF *keydef;
MI_COLUMNDEF *recinfo,*recinfo_pos;
HA_KEYSEG *keyseg;
- TABLE_SHARE *share= table->s;
+ TABLE_SHARE *share= table_arg->s;
uint options= share->db_options_in_use;
DBUG_ENTER("ha_myisam::create");
@@ -1442,10 +1502,14 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
pos=table_arg->key_info;
for (i=0; i < share->keys ; i++, pos++)
{
+ if (pos->flags & HA_USES_PARSER)
+ create_flags|= HA_CREATE_RELIES_ON_SQL_LAYER;
keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL));
keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ?
(pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) :
pos->algorithm;
+ keydef[i].block_length= pos->block_size;
+
keydef[i].seg=keyseg;
keydef[i].keysegs=pos->key_parts;
for (j=0 ; j < pos->key_parts ; j++)
@@ -1596,11 +1660,6 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
(ulonglong) 0);
create_info.data_file_length= ((ulonglong) share->max_rows *
share->avg_row_length);
- create_info.raid_type=info->raid_type;
- create_info.raid_chunks= (info->raid_chunks ? info->raid_chunks :
- RAID_DEFAULT_CHUNKS);
- create_info.raid_chunksize= (info->raid_chunksize ? info->raid_chunksize :
- RAID_DEFAULT_CHUNKSIZE);
create_info.data_file_name= info->data_file_name;
create_info.index_file_name= info->index_file_name;
@@ -1614,7 +1673,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
create_flags|= HA_CREATE_DELAY_KEY_WRITE;
/* TODO: Check that the following fn_format is really needed */
- error=mi_create(fn_format(buff,name,"","",2+4),
+ error=mi_create(fn_format(buff,name,"","",MY_UNPACK_FILENAME|MY_APPEND_EXT),
share->keys,keydef,
(uint) (recinfo_pos-recinfo), recinfo,
0, (MI_UNIQUEDEF*) 0,
@@ -1718,3 +1777,38 @@ uint ha_myisam::checksum() const
return (uint)file->state->checksum;
}
+
+bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes)
+{
+ uint options= table->s->db_options_in_use;
+
+ if (info->auto_increment_value != auto_increment_value ||
+ info->data_file_name != data_file_name ||
+ info->index_file_name != index_file_name ||
+ table_changes == IS_EQUAL_NO ||
+ table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
+ return COMPATIBLE_DATA_NO;
+
+ if ((options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM |
+ HA_OPTION_DELAY_KEY_WRITE)) !=
+ (info->table_options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM |
+ HA_OPTION_DELAY_KEY_WRITE)))
+ return COMPATIBLE_DATA_NO;
+ return COMPATIBLE_DATA_YES;
+}
+
+
+mysql_declare_plugin(myisam)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisam_hton,
+ myisam_hton_name,
+ "MySQL AB",
+ myisam_hton_comment,
+ NULL, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ 0
+}
+mysql_declare_plugin_end;