List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:April 4 2011 11:08am
Subject:bzr commit into mysql-5.5 branch (jon.hauglid:3420) Bug#11853126
View as plain text  
#At file:///export/home/x/mysql-5.5-bug11853126/ based on revid:vasil.dimov@stripped

 3420 Jon Olav Hauglid	2011-04-04
      Bug#11853126 RE-ENABLE CONCURRENT READS WHILE CREATING
                   SECONDARY INDEX IN INNODB
      
      The patches for Bug#11751388 and Bug#11784056 enabled concurrent
      reads while creating secondary indexes in InnoDB. However, they
      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. If this happened, InnoDB
      and the server got out of sync with regards to which indexes
      actually existed. Therefore the patch for Bug#11815600 again
      disabled concurrent reads.
      
      This patch re-enables concurrent reads. The original regression
      is fixed by dropping the recently added index if ALTER TABLE
      fails after the index has been added inside InnoDB. An instance
      of the table is then opened in order to rebuild the InnoDB index
      translation table.
      
      Test case added to innodb_mysql_lock.test.

    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-04-04 11:07:59 +0000
@@ -148,3 +148,27 @@ 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);
+# 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
+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-04-04 11:07:59 +0000
@@ -279,6 +279,44 @@ 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 # Connection default
+connection default;
+START TRANSACTION;
+SELECT * FROM t1;
+
+--echo # Connection con1
+--connection con1
+SET lock_wait_timeout=1;
+# Test with two timeouts, as the first version of this patch
+# only worked with one timeout.
+--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-04-04 11:07:59 +0000
@@ -6591,7 +6591,29 @@ 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));
+      table_list->table->m_needs_reopen= true;
+    }
     goto err_new_table_cleanup;
+  }
 
 
   close_all_tables_for_name(thd, table->s,


Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20110404110759-4crwrqwfrdpf16ta.bundle
Thread
bzr commit into mysql-5.5 branch (jon.hauglid:3420) Bug#11853126Jon Olav Hauglid4 Apr