Commit 950e258f authored by marty@linux.site's avatar marty@linux.site

Fixes for fast alter table for ndbcluster

parent 0f967642
...@@ -4687,8 +4687,9 @@ int ha_ndbcluster::create(const char *name, ...@@ -4687,8 +4687,9 @@ int ha_ndbcluster::create(const char *name,
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} }
int ha_ndbcluster::create_handler_files(const char *file) int ha_ndbcluster::create_handler_files(const char *file, HA_CREATE_INFO *info)
{ {
char path[FN_REFLEN];
const char *name; const char *name;
Ndb* ndb; Ndb* ndb;
const NDBTAB *tab; const NDBTAB *tab;
...@@ -4698,16 +4699,21 @@ int ha_ndbcluster::create_handler_files(const char *file) ...@@ -4698,16 +4699,21 @@ int ha_ndbcluster::create_handler_files(const char *file)
DBUG_ENTER("create_handler_files"); DBUG_ENTER("create_handler_files");
DBUG_PRINT("enter", ("file: %s", file));
if (!(ndb= get_ndb())) if (!(ndb= get_ndb()))
DBUG_RETURN(HA_ERR_NO_CONNECTION); DBUG_RETURN(HA_ERR_NO_CONNECTION);
NDBDICT *dict= ndb->getDictionary(); NDBDICT *dict= ndb->getDictionary();
if (!(tab= dict->getTable(m_tabname))) if (!info->frm_only)
DBUG_RETURN(0); // Must be a create, ignore since frm is saved in create DBUG_RETURN(0); // Must be a create, ignore since frm is saved in create
set_dbname(file);
set_tabname(file);
DBUG_PRINT("info", ("m_dbname: %s, m_tabname: %s", m_dbname, m_tabname));
if (!(tab= dict->getTable(m_tabname)))
DBUG_RETURN(0); // Unkown table, must be temporary table
DBUG_ASSERT(get_ndb_share_state(m_share) == NSS_ALTERED); DBUG_ASSERT(get_ndb_share_state(m_share) == NSS_ALTERED);
name= table->s->normalized_path.str; if (readfrm(file, &data, &length) ||
DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, name));
if (readfrm(name, &data, &length) ||
packfrm(data, length, &pack_data, &pack_length)) packfrm(data, length, &pack_data, &pack_length))
{ {
DBUG_PRINT("info", ("Missing frm for %s", m_tabname)); DBUG_PRINT("info", ("Missing frm for %s", m_tabname));
...@@ -4723,6 +4729,7 @@ int ha_ndbcluster::create_handler_files(const char *file) ...@@ -4723,6 +4729,7 @@ int ha_ndbcluster::create_handler_files(const char *file)
my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
} }
set_ndb_share_state(m_share, NSS_INITIAL); set_ndb_share_state(m_share, NSS_INITIAL);
free_share(&m_share); // Decrease ref_count free_share(&m_share); // Decrease ref_count
...@@ -4829,6 +4836,15 @@ int ha_ndbcluster::create_ndb_index(const char *name, ...@@ -4829,6 +4836,15 @@ int ha_ndbcluster::create_ndb_index(const char *name,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/*
Prepare for an on-line alter table
*/
void ha_ndbcluster::prepare_for_alter()
{
ndbcluster_get_share(m_share); // Increase ref_count
set_ndb_share_state(m_share, NSS_ALTERED);
}
/* /*
Add an index on-line to a table Add an index on-line to a table
*/ */
...@@ -4841,7 +4857,7 @@ int ha_ndbcluster::add_index(TABLE *table_arg, ...@@ -4841,7 +4857,7 @@ int ha_ndbcluster::add_index(TABLE *table_arg,
int error= 0; int error= 0;
uint idx; uint idx;
DBUG_ASSERT(m_share->state == NSS_INITIAL); DBUG_ASSERT(m_share->state == NSS_ALTERED);
for (idx= 0; idx < num_of_keys; idx++) for (idx= 0; idx < num_of_keys; idx++)
{ {
KEY *key= key_info + idx; KEY *key= key_info + idx;
...@@ -4857,10 +4873,10 @@ int ha_ndbcluster::add_index(TABLE *table_arg, ...@@ -4857,10 +4873,10 @@ int ha_ndbcluster::add_index(TABLE *table_arg,
if((error= create_index(key_info[idx].name, key, idx_type, idx))) if((error= create_index(key_info[idx].name, key, idx_type, idx)))
break; break;
} }
if (!error) if (error)
{ {
ndbcluster_get_share(m_share); // Increase ref_count set_ndb_share_state(m_share, NSS_INITIAL);
set_ndb_share_state(m_share, NSS_ALTERED); free_share(&m_share); // Decrease ref_count
} }
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -4885,7 +4901,7 @@ int ha_ndbcluster::prepare_drop_index(TABLE *table_arg, ...@@ -4885,7 +4901,7 @@ int ha_ndbcluster::prepare_drop_index(TABLE *table_arg,
uint *key_num, uint num_of_keys) uint *key_num, uint num_of_keys)
{ {
DBUG_ENTER("ha_ndbcluster::prepare_drop_index"); DBUG_ENTER("ha_ndbcluster::prepare_drop_index");
DBUG_ASSERT(m_share->state == NSS_INITIAL); DBUG_ASSERT(m_share->state == NSS_ALTERED);
// Mark indexes for deletion // Mark indexes for deletion
uint idx; uint idx;
for (idx= 0; idx < num_of_keys; idx++) for (idx= 0; idx < num_of_keys; idx++)
...@@ -4898,8 +4914,6 @@ int ha_ndbcluster::prepare_drop_index(TABLE *table_arg, ...@@ -4898,8 +4914,6 @@ int ha_ndbcluster::prepare_drop_index(TABLE *table_arg,
Thd_ndb *thd_ndb= get_thd_ndb(thd); Thd_ndb *thd_ndb= get_thd_ndb(thd);
Ndb *ndb= thd_ndb->ndb; Ndb *ndb= thd_ndb->ndb;
renumber_indexes(ndb, table_arg); renumber_indexes(ndb, table_arg);
ndbcluster_get_share(m_share); // Increase ref_count
set_ndb_share_state(m_share, NSS_ALTERED);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -595,6 +595,7 @@ class ha_ndbcluster: public handler ...@@ -595,6 +595,7 @@ class ha_ndbcluster: public handler
const char * table_type() const; const char * table_type() const;
const char ** bas_ext() const; const char ** bas_ext() const;
ulong table_flags(void) const; ulong table_flags(void) const;
void prepare_for_alter();
int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys); int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys);
int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys); int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys);
int final_drop_index(TABLE *table_arg); int final_drop_index(TABLE *table_arg);
...@@ -609,7 +610,7 @@ class ha_ndbcluster: public handler ...@@ -609,7 +610,7 @@ class ha_ndbcluster: public handler
int rename_table(const char *from, const char *to); int rename_table(const char *from, const char *to);
int delete_table(const char *name); int delete_table(const char *name);
int create(const char *name, TABLE *form, HA_CREATE_INFO *info); int create(const char *name, TABLE *form, HA_CREATE_INFO *info);
int create_handler_files(const char *file); int create_handler_files(const char *file, HA_CREATE_INFO *info);
int get_default_no_partitions(ulonglong max_rows); int get_default_no_partitions(ulonglong max_rows);
bool get_no_parts(const char *name, uint *no_parts); bool get_no_parts(const char *name, uint *no_parts);
void set_auto_partitions(partition_info *part_info); void set_auto_partitions(partition_info *part_info);
......
...@@ -562,6 +562,7 @@ int ha_partition::rename_table(const char *from, const char *to) ...@@ -562,6 +562,7 @@ int ha_partition::rename_table(const char *from, const char *to)
SYNOPSIS SYNOPSIS
create_handler_files() create_handler_files()
name Full path of table name name Full path of table name
create_info Create info generated for CREATE TABLE
RETURN VALUE RETURN VALUE
>0 Error >0 Error
...@@ -575,7 +576,8 @@ int ha_partition::rename_table(const char *from, const char *to) ...@@ -575,7 +576,8 @@ int ha_partition::rename_table(const char *from, const char *to)
and types of engines in the partitions. and types of engines in the partitions.
*/ */
int ha_partition::create_handler_files(const char *name) int ha_partition::create_handler_files(const char *name,
HA_CREATE_INFO *create_info)
{ {
DBUG_ENTER("ha_partition::create_handler_files()"); DBUG_ENTER("ha_partition::create_handler_files()");
......
...@@ -179,7 +179,8 @@ class ha_partition :public handler ...@@ -179,7 +179,8 @@ class ha_partition :public handler
virtual int rename_table(const char *from, const char *to); virtual int rename_table(const char *from, const char *to);
virtual int create(const char *name, TABLE *form, virtual int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); HA_CREATE_INFO *create_info);
virtual int create_handler_files(const char *name); virtual int create_handler_files(const char *name,
HA_CREATE_INFO *create_info);
virtual void update_create_info(HA_CREATE_INFO *create_info); virtual void update_create_info(HA_CREATE_INFO *create_info);
virtual char *update_table_comment(const char *comment); virtual char *update_table_comment(const char *comment);
virtual int change_partitions(HA_CREATE_INFO *create_info, virtual int change_partitions(HA_CREATE_INFO *create_info,
......
...@@ -1338,6 +1338,7 @@ class handler :public Sql_alloc ...@@ -1338,6 +1338,7 @@ class handler :public Sql_alloc
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
virtual void prepare_for_alter() { return; }
virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
{ return (HA_ERR_WRONG_COMMAND); } { return (HA_ERR_WRONG_COMMAND); }
virtual int prepare_drop_index(TABLE *table_arg, uint *key_num, virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
...@@ -1378,7 +1379,8 @@ class handler :public Sql_alloc ...@@ -1378,7 +1379,8 @@ class handler :public Sql_alloc
virtual void drop_table(const char *name); virtual void drop_table(const char *name);
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0; virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
virtual int create_handler_files(const char *name) { return FALSE;} virtual int create_handler_files(const char *name, HA_CREATE_INFO *info)
{ return FALSE;}
virtual int change_partitions(HA_CREATE_INFO *create_info, virtual int change_partitions(HA_CREATE_INFO *create_info,
const char *path, const char *path,
......
...@@ -347,7 +347,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) ...@@ -347,7 +347,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
lpt->create_info, lpt->new_create_list, lpt->key_count, lpt->create_info, lpt->new_create_list, lpt->key_count,
lpt->key_info_buffer, lpt->table->file)) || lpt->key_info_buffer, lpt->table->file)) ||
((flags & WFRM_CREATE_HANDLER_FILES) && ((flags & WFRM_CREATE_HANDLER_FILES) &&
lpt->table->file->create_handler_files(path))) lpt->table->file->create_handler_files(path, lpt->create_info)))
{ {
error= 1; error= 1;
goto end; goto end;
...@@ -3964,6 +3964,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -3964,6 +3964,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
char index_file[FN_REFLEN], data_file[FN_REFLEN]; char index_file[FN_REFLEN], data_file[FN_REFLEN];
char path[FN_REFLEN];
char reg_path[FN_REFLEN+1]; char reg_path[FN_REFLEN+1];
ha_rows copied,deleted; ha_rows copied,deleted;
ulonglong next_insert_id; ulonglong next_insert_id;
...@@ -4000,6 +4001,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -4000,6 +4001,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
new_db= db; new_db= db;
build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext); build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext);
build_table_filename(path, sizeof(path), db, table_name, "");
used_fields=create_info->used_fields; used_fields=create_info->used_fields;
...@@ -4773,6 +4775,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -4773,6 +4775,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
KEY_PART_INFO *part_end; KEY_PART_INFO *part_end;
DBUG_PRINT("info", ("No new_table, checking add/drop index")); DBUG_PRINT("info", ("No new_table, checking add/drop index"));
table->file->prepare_for_alter();
if (index_add_count) if (index_add_count)
{ {
#ifdef XXX_TO_BE_DONE_LATER_BY_WL3020_AND_WL1892 #ifdef XXX_TO_BE_DONE_LATER_BY_WL3020_AND_WL1892
...@@ -4788,7 +4791,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -4788,7 +4791,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error= (mysql_create_frm(thd, reg_path, db, table_name, error= (mysql_create_frm(thd, reg_path, db, table_name,
create_info, prepared_create_list, key_count, create_info, prepared_create_list, key_count,
key_info_buffer, table->file) || key_info_buffer, table->file) ||
table->file->create_handler_files(reg_path)); table->file->create_handler_files(path, create_info));
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
if (error) if (error)
goto err; goto err;
...@@ -4834,7 +4837,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -4834,7 +4837,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error= (mysql_create_frm(thd, reg_path, db, table_name, error= (mysql_create_frm(thd, reg_path, db, table_name,
create_info, prepared_create_list, key_count, create_info, prepared_create_list, key_count,
key_info_buffer, table->file) || key_info_buffer, table->file) ||
table->file->create_handler_files(reg_path)); table->file->create_handler_files(path, create_info));
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
if (error) if (error)
goto err; goto err;
...@@ -4904,19 +4907,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -4904,19 +4907,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
} }
/*end of if (index_drop_count)*/ /*end of if (index_drop_count)*/
if (index_add_count || index_drop_count) /*
{ The final .frm file is already created as a temporary file
/* and will be renamed to the original table name later.
The final .frm file is already created as a temporary file */
and will be renamed to the original table name later.
*/
/* Need to commit before a table is unlocked (NDB requirement). */ /* Need to commit before a table is unlocked (NDB requirement). */
DBUG_PRINT("info", ("Committing after add/drop index")); DBUG_PRINT("info", ("Committing before unlocking table"));
if (ha_commit_stmt(thd) || ha_commit(thd)) if (ha_commit_stmt(thd) || ha_commit(thd))
goto err; goto err;
committed= 1; committed= 1;
}
} }
/*end of if (! new_table) for add/drop index*/ /*end of if (! new_table) for add/drop index*/
...@@ -5061,7 +5061,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -5061,7 +5061,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
} }
/* Tell the handler that a new frm file is in place. */ /* Tell the handler that a new frm file is in place. */
if (table->file->create_handler_files(reg_path)) if (table->file->create_handler_files(path, create_info))
{ {
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
goto err; goto err;
......
...@@ -330,7 +330,7 @@ int rea_create_table(THD *thd, const char *path, ...@@ -330,7 +330,7 @@ int rea_create_table(THD *thd, const char *path,
// Make sure mysql_create_frm din't remove extension // Make sure mysql_create_frm din't remove extension
DBUG_ASSERT(*fn_rext(frm_name)); DBUG_ASSERT(*fn_rext(frm_name));
if (file->create_handler_files(path)) if (file->create_handler_files(path, create_info))
goto err_handler; goto err_handler;
if (!create_info->frm_only && ha_create_table(thd, path, db, table_name, if (!create_info->frm_only && ha_create_table(thd, path, db, table_name,
create_info,0)) create_info,0))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment