summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc75
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;