List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:March 30 2011 1:27pm
Subject:bzr commit into mysql-5.5 branch (jon.hauglid:3415) Bug#11853126
View as plain text  
#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#11853126Jon Olav Hauglid30 Mar