From 55aa43e2f52acfe88c633f6aeec3089ef68b0e19 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jun 2007 22:53:50 +0500 Subject: [PATCH] Fix for bug #28652: MySQL (with-debug=full) asserts when alter table operations Problem: we may create a deadlock committing changes in the mysql_alter_table() when LOCK_open is set. Moreover, "in some variants of the ALTER TABLE commit happens earlier, outside of LOCK_open, in other later - inside. It's no good, a storage engine code that is called in between could expect a consistency - either there is a transaction or there is not". Fix: move the commit to happen earlier and outside of the LOCK_open. mysql-test/r/innodb_mysql.result: Fix for bug #28652: MySQL (with-debug=full) asserts when alter table operations - test result. mysql-test/t/innodb_mysql.test: Fix for bug #28652: MySQL (with-debug=full) asserts when alter table operations - test case. sql/sql_table.cc: Fix for bug #28652: MySQL (with-debug=full) asserts when alter table operations - commit moved to happen earlier in the mysql_alter_table(), now we commit changes at the same time as in case when a temporary table is used. --- mysql-test/r/innodb_mysql.result | 8 ++++++++ mysql-test/t/innodb_mysql.test | 8 ++++++++ sql/sql_table.cc | 21 +++++++++------------ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 45cb116f08b..34eb831e7db 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -617,4 +617,12 @@ EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range idx1,idx2 idx1 9 NULL 2 Using where; Using index DROP TABLE t1,t2; +create table t1(a int) engine=innodb; +alter table t1 comment '123'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='123' +drop table t1; End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index d9e50add8bf..e6d94fe1627 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -597,4 +597,12 @@ EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785; DROP TABLE t1,t2; +# +# Bug #28652: assert when alter innodb table operation +# +create table t1(a int) engine=innodb; +alter table t1 comment '123'; +show create table t1; +drop table t1; + --echo End of 5.0 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 079cc0d6456..27d049e2d06 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3776,6 +3776,9 @@ view_err: alter_info->keys_onoff); table->file->external_lock(thd, F_UNLCK); VOID(pthread_mutex_unlock(&LOCK_open)); + error= ha_commit_stmt(thd); + if (ha_commit(thd)) + error= 1; } thd->last_insert_id=next_insert_id; // Needed for correct log @@ -3946,16 +3949,6 @@ view_err: goto err; } } - /* The ALTER TABLE is always in its own transaction */ - error = ha_commit_stmt(thd); - if (ha_commit(thd)) - error=1; - if (error) - { - VOID(pthread_mutex_unlock(&LOCK_open)); - broadcast_refresh(); - goto err; - } thd->proc_info="end"; if (mysql_bin_log.is_open()) { @@ -4165,8 +4158,12 @@ copy_data_between_tables(TABLE *from,TABLE *to, } to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); - ha_enable_transaction(thd,TRUE); - + if (ha_enable_transaction(thd, TRUE)) + { + error= 1; + goto err; + } + /* Ensure that the new table is saved properly to disk so that we can do a rename