List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:July 8 2010 12:46pm
Subject:bzr commit into mysql-trunk-bugfixing branch (mattias.jonsson:3093) Bug#53676
View as plain text  
#At file:///Users/mattiasj/mysql-bzr/b53676-trunk-bf/ based on revid:mattias.jonsson@stripped

 3093 Mattias Jonsson	2010-07-08
      Bug#53676: Unexpected errors and possible table corruption on
                 ADD PARTITION and LOCK TABLE
      
      Review fixes after Mikaels review.
     @ sql/sql_partition.cc
        Changed from using mysql_unlock_tables to use mysql_lock_remove
        instead, to avoid unlocking tables under LOCK TABLE.
        
        Fixed comments and style.

    modified:
      sql/sql_partition.cc
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2010-06-11 11:03:03 +0000
+++ b/sql/sql_partition.cc	2010-07-08 12:46:07 +0000
@@ -6133,9 +6133,10 @@ static bool write_log_add_change_partiti
     goto error;
   log_entry= part_info->first_log_entry;
 
-  /* Reuse the old execute ddl_log_entry */
   if (write_execute_ddl_log_entry(log_entry->entry_pos,
-                                    FALSE, &exec_log_entry))
+                                  FALSE,
+                                  /* Reuse the old execute ddl_log_entry */
+                                  &exec_log_entry))
     goto error;
   mysql_mutex_unlock(&LOCK_gdl);
   set_part_info_exec_log_entry(part_info, exec_log_entry);
@@ -6161,9 +6162,15 @@ error:
     TRUE                     Error
     FALSE                    Success
   DESCRIPTION
-    We will write log entries that specify to remove all partitions reorganised,
-    to rename others to reflect the new naming scheme and to install the shadow
-    frm file.
+    We will write log entries that specify to
+    1) Install the shadow frm file.
+    2) Remove all partitions reorganized. (To be able to reorganize a partition
+       to the same name. Like in REORGANIZE p0 INTO (p0, p1),
+       so that the later rename from the new p0-temporary name to p0 don't
+       fail because the partition already exists.
+    3) Rename others to reflect the new naming scheme.
+
+    Note that it is written in the ddl log in reverse.
 */
 
 static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
@@ -6323,7 +6330,7 @@ void handle_alter_part_error(ALTER_PARTI
       But we do not want to remove the table instance since we need the
       part_info object.
     */
-    mysql_unlock_tables(thd, thd->lock);
+    mysql_lock_remove(thd, thd->lock, table);
     thd->lock= NULL;
     table->file->close();
     table->db_stat= 0;
@@ -6431,6 +6438,22 @@ void handle_alter_part_error(ALTER_PARTI
 }
 
 
+/**
+  Downgrade an exclusive MDL lock if under LOCK TABLE.
+
+  If we don't downgrade the lock, it will not be downgraded or released
+  until the table is unlocked, resulting in blocking other threads using
+  the table.
+*/
+
+static void downgrade_mdl_if_lock_tables_mode(THD *thd, MDL_ticket *ticket,
+                                              enum_mdl_type type)
+{
+  if (thd->locked_tables_mode)
+    ticket->downgrade_exclusive_lock(type);
+}
+
+
 /*
   Actually perform the change requested by ALTER TABLE of partitions
   previously prepared.
@@ -6580,7 +6603,7 @@ uint fast_alter_partition_table(THD *thd
       4) Close all tables that have already been opened but didn't stumble on
          the abort locked previously. This is done as part of the
          alter_close_tables call.
-      7) Write the bin log
+      5) Write the bin log
          Unfortunately the writing of the binlog is not synchronised with
          other logging activities. So no matter in which order the binlog
          is written compared to other activities there will always be cases
@@ -6591,12 +6614,12 @@ uint fast_alter_partition_table(THD *thd
          require writing the statement first in the ddl log and then
          when recovering from the crash read the binlog and insert it into
          the binlog if not written already.
-      8) Install the previously written shadow frm file
-      9) Prepare handlers for drop of partitions
-      10) Drop the partitions
-      11) Remove entries from ddl log
-      12) Reopen table if under lock tables
-      13) Complete query
+      6) Install the previously written shadow frm file
+      7) Prepare handlers for drop of partitions
+      8) Drop the partitions
+      9) Remove entries from ddl log
+      10) Reopen table if under lock tables
+      11) Complete query
 
       We insert Error injections at all places where it could be interesting
       to test if recovery is properly done.
@@ -6614,8 +6637,8 @@ uint fast_alter_partition_table(THD *thd
         write_log_drop_partition(lpt) ||
         ERROR_INJECT_CRASH("crash_drop_partition_4") ||
         ERROR_INJECT_ERROR("fail_drop_partition_4") ||
-        (close_table_on_failure= FALSE) ||
-        (not_completed= FALSE) ||
+        (close_table_on_failure= FALSE, FALSE) ||
+        (not_completed= FALSE, FALSE) ||
         alter_close_tables(lpt) ||
         ERROR_INJECT_CRASH("crash_drop_partition_5") ||
         ERROR_INJECT_ERROR("fail_drop_partition_5") ||
@@ -6624,9 +6647,9 @@ uint fast_alter_partition_table(THD *thd
                         thd->query(), thd->query_length()), FALSE)) ||
         ERROR_INJECT_CRASH("crash_drop_partition_6") ||
         ERROR_INJECT_ERROR("fail_drop_partition_6") ||
-        ((frm_install= TRUE), FALSE) ||
+        (frm_install= TRUE, FALSE) ||
         mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
-        ((frm_install= FALSE), FALSE) ||
+        (frm_install= FALSE, FALSE) ||
         ERROR_INJECT_CRASH("crash_drop_partition_7") ||
         ERROR_INJECT_ERROR("fail_drop_partition_7") ||
         mysql_drop_partitions(lpt) ||
@@ -6662,7 +6685,7 @@ uint fast_alter_partition_table(THD *thd
          can release all other locks on the table and since no one can open
          the table, there can be no new threads accessing the table. They
          will be hanging on this exclusive lock.
-      3) Log the changes to happen in ddl log
+      3) Write an entry to remove the new parttions if crash occurs
       4) Add the new partitions.
       5) Close all instances of the table and remove them from the table cache.
       6) Write binlog
@@ -6691,7 +6714,7 @@ uint fast_alter_partition_table(THD *thd
         mysql_change_partitions(lpt) ||
         ERROR_INJECT_CRASH("crash_add_partition_5") ||
         ERROR_INJECT_ERROR("fail_add_partition_5") ||
-        (close_table_on_failure= FALSE) ||
+        (close_table_on_failure= FALSE, FALSE) ||
         alter_close_tables(lpt) ||
         ERROR_INJECT_CRASH("crash_add_partition_6") ||
         ERROR_INJECT_ERROR("fail_add_partition_6") ||
@@ -6701,7 +6724,8 @@ uint fast_alter_partition_table(THD *thd
         ERROR_INJECT_CRASH("crash_add_partition_7") ||
         ERROR_INJECT_ERROR("fail_add_partition_7") ||
         write_log_rename_frm(lpt) ||
-        ((frm_install= TRUE), (not_completed= FALSE)) ||
+        (frm_install= TRUE, FALSE) ||
+        (not_completed= FALSE, FALSE) ||
         ERROR_INJECT_CRASH("crash_add_partition_8") ||
         ERROR_INJECT_ERROR("fail_add_partition_8") ||
         mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
@@ -6821,8 +6845,7 @@ uint fast_alter_partition_table(THD *thd
       goto err;
     }
   }
-  if (thd->locked_tables_mode)
-    mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE);
+  downgrade_mdl_if_lock_tables_mode(thd, mdl_ticket, MDL_SHARED_NO_READ_WRITE);
   /*
     A final step is to write the query to the binlog and send ok to the
     user
@@ -6831,8 +6854,7 @@ uint fast_alter_partition_table(THD *thd
                                  table_list, FALSE, NULL,
                                  written_bin_log));
 err:
-  if (thd->locked_tables_mode)
-    mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE);
+  downgrade_mdl_if_lock_tables_mode(thd, mdl_ticket, MDL_SHARED_NO_READ_WRITE);
   table->m_needs_reopen= TRUE;
   close_thread_tables(thd);
   DBUG_RETURN(TRUE);


Attachment: [text/bzr-bundle] bzr/mattias.jonsson@oracle.com-20100708124607-muxp214s8a3ikefk.bundle
Thread
bzr commit into mysql-trunk-bugfixing branch (mattias.jonsson:3093) Bug#53676Mattias Jonsson8 Jul