mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixes for fast alter table for ndbcluster
This commit is contained in:
@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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
|
|||||||
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
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
|
|
||||||
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 @@ public:
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
/*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,
|
|||||||
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,
|
|||||||
|
|
||||||
// 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))
|
||||||
|
Reference in New Issue
Block a user