#At file:///export/home/x/mysql-5.5-bug11853126/ based on revid:sergey.glukhov@stripped
3415 Jon Olav Hauglid 2011-03-30
Bug#11853126 RE-ENABLE CONCURRENT READS WHILE CREATING
SECONDARY INDEX IN INNODB
** This is a draft patch **
Allowing concurrent reads during secondary index creation
in InnoDB introduced a regression. This regression occured
if ALTER TABLE failed after the index had been added, for
example during the lock upgrade needed to update .FRM.
This patch tries to fix the problem by dropping the recently
added index in such cases and then reopnening the table in
order to rebuild the InnoDB index translation table.
However, as the test case shows this patch is not a complete
solution in it's current state. For discussion purposes only.
modified:
mysql-test/r/innodb_mysql_lock.result
mysql-test/t/innodb_mysql_lock.test
sql/sql_table.cc
=== modified file 'mysql-test/r/innodb_mysql_lock.result'
--- a/mysql-test/r/innodb_mysql_lock.result 2010-06-26 20:23:28 +0000
+++ b/mysql-test/r/innodb_mysql_lock.result 2011-03-30 13:27:50 +0000
@@ -148,3 +148,42 @@ COMMIT;
# Connection default
DROP TABLE t1, t2;
DROP VIEW v1;
+#
+# Bug#11815600 [ERROR] INNODB COULD NOT FIND INDEX PRIMARY
+# KEY NO 0 FOR TABLE IN ERROR LOG
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (id INT PRIMARY KEY, value INT) ENGINE = InnoDB;
+INSERT INTO t1 VALUES (1, 12345);
+# Test 1: One timeout. (this works)
+# Connection default
+START TRANSACTION;
+SELECT * FROM t1;
+id value
+1 12345
+# Connection con1
+SET lock_wait_timeout=1;
+ALTER TABLE t1 ADD INDEX idx(value);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Connection default
+SELECT * FROM t1;
+id value
+1 12345
+COMMIT;
+# Test 2: Two timeouts. (this doesn't work)
+START TRANSACTION;
+SELECT * FROM t1;
+id value
+1 12345
+# Connection con1
+SET lock_wait_timeout=1;
+ALTER TABLE t1 ADD INDEX idx(value);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ALTER TABLE t1 ADD INDEX idx(value);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Connection default
+SELECT * FROM t1;
+id value
+1 12345
+COMMIT;
+DROP TABLE t1;
=== modified file 'mysql-test/t/innodb_mysql_lock.test'
--- a/mysql-test/t/innodb_mysql_lock.test 2010-08-06 11:29:37 +0000
+++ b/mysql-test/t/innodb_mysql_lock.test 2011-03-30 13:27:50 +0000
@@ -279,6 +279,60 @@ disconnect con2;
disconnect con3;
+--echo #
+--echo # Bug#11815600 [ERROR] INNODB COULD NOT FIND INDEX PRIMARY
+--echo # KEY NO 0 FOR TABLE IN ERROR LOG
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (id INT PRIMARY KEY, value INT) ENGINE = InnoDB;
+INSERT INTO t1 VALUES (1, 12345);
+
+--connect (con1,localhost,root)
+
+--echo # Test 1: One timeout. (this works)
+
+--echo # Connection default
+connection default;
+START TRANSACTION;
+SELECT * FROM t1;
+
+--echo # Connection con1
+--connection con1
+SET lock_wait_timeout=1;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 ADD INDEX idx(value);
+
+--echo # Connection default
+--connection default
+SELECT * FROM t1;
+COMMIT;
+
+--echo # Test 2: Two timeouts. (this doesn't work)
+
+START TRANSACTION;
+SELECT * FROM t1;
+
+--echo # Connection con1
+--connection con1
+SET lock_wait_timeout=1;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 ADD INDEX idx(value);
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 ADD INDEX idx(value);
+
+--echo # Connection default
+--connection default
+SELECT * FROM t1;
+COMMIT;
+
+DROP TABLE t1;
+disconnect con1;
+
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2011-03-25 14:03:44 +0000
+++ b/sql/sql_table.cc 2011-03-30 13:27:50 +0000
@@ -6591,7 +6591,28 @@ bool mysql_alter_table(THD *thd,char *ne
my_casedn_str(files_charset_info, old_name);
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
+ {
+ // If lock upgrade fails, we must drop any indexes recently added.
+ if (index_add_count)
+ {
+ /*
+ Temporarily set table-key_info to include information about the
+ indexes added above that we now need to drop.
+ */
+ KEY *save_key_info= table->key_info;
+ table->key_info= key_info_buffer;
+ if ((error= table->file->prepare_drop_index(table, index_add_buffer,
+ index_add_count)))
+ table->file->print_error(error, MYF(0));
+ else if ((error= table->file->final_drop_index(table)))
+ table->file->print_error(error, MYF(0));
+ table->key_info= save_key_info;
+ // Reopen the table to rebuild the index translation table.
+ Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
+ DBUG_ASSERT(!open_table(thd, table_list, thd->mem_root, &ot_ctx));
+ }
goto err_new_table_cleanup;
+ }
close_all_tables_for_name(thd, table->s,
Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20110330132750-67irxw0d7esbp6zg.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5 branch (jon.hauglid:3415) Bug#11853126 | Jon Olav Hauglid | 30 Mar |