diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bd5f381b8b8..3f0a0326c84 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4268,6 +4268,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, Alter_info *alter_info) { bool result; + bool is_trans= FALSE; DBUG_ENTER("mysql_create_table"); /* @@ -4282,7 +4283,6 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, /* Got lock. */ DEBUG_SYNC(thd, "locked_table_name"); - bool is_trans; result= mysql_create_table_no_lock(thd, create_table->db, create_table->table_name, create_info, alter_info, FALSE, 0, &is_trans); @@ -4454,6 +4454,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, HA_CREATE_INFO local_create_info; Alter_info local_alter_info; bool res= TRUE; + bool is_trans= FALSE; uint not_used; DBUG_ENTER("mysql_create_like_table"); @@ -4503,7 +4504,6 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, /* Reset auto-increment counter for the new table. */ local_create_info.auto_increment_value= 0; - bool is_trans; if ((res= mysql_create_table_no_lock(thd, table->db, table->table_name, &local_create_info, &local_alter_info, FALSE, 0, &is_trans))) @@ -6740,6 +6740,54 @@ err_with_mdl: } /* mysql_alter_table */ + + +/** + Prepare the transaction for the alter table's copy phase. +*/ + +bool mysql_trans_prepare_alter_copy_data(THD *thd) +{ + DBUG_ENTER("mysql_prepare_alter_copy_data"); + /* + Turn off recovery logging since rollback of an alter table is to + delete the new table so there is no need to log the changes to it. + + This needs to be done before external_lock. + */ + if (ha_enable_transaction(thd, FALSE)) + DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); +} + + +/** + Commit the copy phase of the alter table. +*/ + +bool mysql_trans_commit_alter_copy_data(THD *thd) +{ + bool error= FALSE; + DBUG_ENTER("mysql_commit_alter_copy_data"); + + if (ha_enable_transaction(thd, TRUE)) + DBUG_RETURN(TRUE); + + /* + Ensure that the new table is saved properly to disk before installing + the new .frm. + And that InnoDB's internal latches are released, to avoid deadlock + when waiting on other instances of the table before rename (Bug#54747). + */ + if (trans_commit_stmt(thd)) + error= TRUE; + if (trans_commit_implicit(thd)) + error= TRUE; + + DBUG_RETURN(error); +} + + static int copy_data_between_tables(TABLE *from,TABLE *to, List<Create_field> &create, @@ -6766,14 +6814,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ulonglong prev_insert_id; DBUG_ENTER("copy_data_between_tables"); - /* - Turn off recovery logging since rollback of an alter table is to - delete the new table so there is no need to log the changes to it. - - This needs to be done before external_lock - */ - error= ha_enable_transaction(thd, FALSE); - if (error) + if (mysql_trans_prepare_alter_copy_data(thd)) DBUG_RETURN(-1); if (!(copy= new Copy_field[to->s->fields])) @@ -6932,20 +6973,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, } to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); - if (ha_enable_transaction(thd, TRUE)) - { + if (mysql_trans_commit_alter_copy_data(thd)) error= 1; - goto err; - } - - /* - Ensure that the new table is saved properly to disk so that we - can do a rename - */ - if (trans_commit_stmt(thd)) - error=1; - if (trans_commit_implicit(thd)) - error=1; err: thd->variables.sql_mode= save_sql_mode; |