MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:May 10 2010 1:35pm
Subject:bzr commit into mysql-pe branch (mattias.jonsson:4065)
View as plain text  
#At file:///Users/mattiasj/clones/bzrroot/topush-mysql-pe_2/ based on revid:martin.hansson@stripped

 4065 Mattias Jonsson	2010-05-10 [merge]
      merge

    added:
      mysql-test/suite/parts/r/partition_debug_sync_innodb.result
      mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt
      mysql-test/suite/parts/t/partition_debug_sync_innodb.test
    modified:
      sql/authors.h
      sql/ha_ndbcluster_binlog.cc
      sql/ha_partition.cc
      sql/sql_base.cc
      sql/sql_base.h
      sql/sql_partition.cc
      sql/sql_show.cc
      sql/tztime.cc
=== added file 'mysql-test/suite/parts/r/partition_debug_sync_innodb.result'
--- a/mysql-test/suite/parts/r/partition_debug_sync_innodb.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/parts/r/partition_debug_sync_innodb.result	2010-05-10 13:09:49 +0000
@@ -0,0 +1,61 @@
+#
+# Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with
+#            concurrent I_S query
+create table t1 (a int)
+engine = innodb
+partition by range (a)
+(partition p0 values less than MAXVALUE);
+insert into t1 values (1), (11), (21), (33);
+SELECT * FROM t1;
+a
+1
+11
+21
+33
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
+t1#P#p0.ibd
+t1.frm
+t1.par
+SET DEBUG_SYNC='before_open_in_get_all_tables SIGNAL parked WAIT_FOR open';
+SET DEBUG_SYNC='partition_open_error SIGNAL alter WAIT_FOR finish';
+SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test';
+SET DEBUG_SYNC = 'now WAIT_FOR parked';
+# When waiting for the name lock in get_all_tables in sql_show.cc
+# this will not be concurrent any more, thus the TIMEOUT
+SET DEBUG_SYNC = 'before_rename_partitions SIGNAL open WAIT_FOR alter TIMEOUT 1';
+# Needs to be executed twice, since first is this 'SET DEBUG_SYNC ...'
+SET DEBUG_SYNC = 'before_close_thread_tables SIGNAL finish EXECUTE 2';
+ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
+(PARTITION p0 VALUES LESS THAN (10),
+PARTITION p10 VALUES LESS THAN MAXVALUE);
+Warnings:
+Warning	1639	debug sync point wait timed out
+TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	PARTITION_NAME	SUBPARTITION_NAME	PARTITION_ORDINAL_POSITION	SUBPARTITION_ORDINAL_POSITION	PARTITION_METHOD	SUBPARTITION_METHOD	PARTITION_EXPRESSION	SUBPARTITION_EXPRESSION	PARTITION_DESCRIPTION	TABLE_ROWS	AVG_ROW_LENGTH	DATA_LENGTH	MAX_DATA_LENGTH	INDEX_LENGTH	DATA_FREE	CREATE_TIME	UPDATE_TIME	CHECK_TIME	CHECKSUM	PARTITION_COMMENT	NODEGROUP	TABLESPACE_NAME
+def	test	t1	p0	NULL	1	NULL	RANGE	NULL	a	NULL	10	1	16384	16384	NULL	0	0	NULL	NULL	NULL	NULL		default	NULL
+def	test	t1	p10	NULL	2	NULL	RANGE	NULL	a	NULL	MAXVALUE	3	5461	16384	NULL	0	0	NULL	NULL	NULL	NULL		default	NULL
+t1#P#p0.ibd
+t1#P#p10.ibd
+t1.frm
+t1.par
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY RANGE (a)
+(PARTITION p0 VALUES LESS THAN (10) ENGINE = InnoDB,
+ PARTITION p10 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
+SELECT * FROM t1;
+a
+1
+11
+21
+33
+drop table t1;
+SET DEBUG_SYNC = 'RESET';

=== added file 'mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt'
--- a/mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt	2010-03-17 14:10:41 +0000
@@ -0,0 +1 @@
+--innodb_file_per_table=1

=== added file 'mysql-test/suite/parts/t/partition_debug_sync_innodb.test'
--- a/mysql-test/suite/parts/t/partition_debug_sync_innodb.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test	2010-03-17 14:10:41 +0000
@@ -0,0 +1,44 @@
+--source include/have_innodb.inc
+--source include/have_partition.inc
+--source include/have_debug_sync.inc
+
+let $MYSQLD_DATADIR=`SELECT @@datadir`;
+
+--echo #
+--echo # Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with
+--echo #            concurrent I_S query
+create table t1 (a int)
+engine = innodb
+partition by range (a)
+(partition p0 values less than MAXVALUE);
+insert into t1 values (1), (11), (21), (33);
+SELECT * FROM t1;
+SHOW CREATE TABLE t1;
+--list_files $MYSQLD_DATADIR/test
+
+SET DEBUG_SYNC='before_open_in_get_all_tables SIGNAL parked WAIT_FOR open';
+SET DEBUG_SYNC='partition_open_error SIGNAL alter WAIT_FOR finish';
+send
+SELECT * FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test';
+
+connect (con1, localhost, root,,);
+SET DEBUG_SYNC = 'now WAIT_FOR parked';
+--echo # When waiting for the name lock in get_all_tables in sql_show.cc
+--echo # this will not be concurrent any more, thus the TIMEOUT
+SET DEBUG_SYNC = 'before_rename_partitions SIGNAL open WAIT_FOR alter TIMEOUT 1';
+--echo # Needs to be executed twice, since first is this 'SET DEBUG_SYNC ...'
+SET DEBUG_SYNC = 'before_close_thread_tables SIGNAL finish EXECUTE 2';
+--error 0,ER_TABLE_EXISTS_ERROR
+ALTER TABLE t1 REORGANIZE PARTITION p0 INTO
+(PARTITION p0 VALUES LESS THAN (10),
+ PARTITION p10 VALUES LESS THAN MAXVALUE);
+
+disconnect con1;
+connection default;
+--reap
+--list_files $MYSQLD_DATADIR/test
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+drop table t1;
+--list_files $MYSQLD_DATADIR/test
+SET DEBUG_SYNC = 'RESET';

=== modified file 'sql/authors.h'
--- a/sql/authors.h	2010-01-07 05:48:46 +0000
+++ b/sql/authors.h	2010-05-10 13:09:49 +0000
@@ -80,6 +80,7 @@ struct show_table_authors_st show_table_
   { "Eric Herman", "Amsterdam, Netherlands", "Bug fixing - federated" },
   { "Andrey Hristov", "Walldorf, Germany", "Event scheduler (5.1)" },
   { "Alexander (Alexi) Ivanov", "St. Petersburg, Russia", "Replication" },
+  { "Mattias Jonsson", "Uppsala, Sweden", "Partitioning" },
   { "Alexander (Salle) Keremidarski", "Sofia, Bulgaria",
     "Bug fixing" },
   { "Mats Kindahl", "Storvreta, Sweden", "Replication" },

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2010-04-09 08:22:10 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2010-05-10 13:09:49 +0000
@@ -37,7 +37,7 @@
 #include "sql_table.h"                         // build_table_filename
 #include "table.h"                             // open_table_from_share
 #include "discover.h"                          // readfrm, writefrm
-#include "lock.h"                              // MYSQL_LOCK_IGNORE_FLUSH,
+#include "lock.h"                              // MYSQL_OPEN_IGNORE_FLUSH,
                                                // mysql_unlock_tables
 #include "sql_parse.h"                         // mysql_parse
 

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2010-04-15 12:51:12 +0000
+++ b/sql/ha_partition.cc	2010-05-10 13:09:49 +0000
@@ -61,6 +61,8 @@
 #include "key.h"
 #include "sql_plugin.h"
 
+#include "debug_sync.h"
+
 static const char *ha_par_ext= ".par";
 #ifdef NOT_USED
 static int free_share(PARTITION_SHARE * share);
@@ -695,6 +697,7 @@ int ha_partition::rename_partitions(THD 
   DBUG_ASSERT(!strcmp(path, get_canonical_filename(m_file[0], path,
                                                    norm_name_buff)));
 
+  DEBUG_SYNC(ha_thd(), "before_rename_partitions");
   if (temp_partitions)
   {
     /*
@@ -2702,6 +2705,7 @@ int ha_partition::open(const char *name,
   DBUG_RETURN(0);
 
 err_handler:
+  DEBUG_SYNC(ha_thd(), "partition_open_error");
   while (file-- != m_file)
     (*file)->close();
   bitmap_free(&m_bulk_insert_started);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-05-09 22:57:56 +0000
+++ b/sql/sql_base.cc	2010-05-10 13:35:06 +0000
@@ -1421,6 +1421,12 @@ void close_thread_tables(THD *thd)
                           table->s->table_name.str, table));
 #endif
 
+#if defined(ENABLED_DEBUG_SYNC)
+  /* debug_sync may not be initialized for some slave threads */
+  if (thd->debug_sync_control)
+    DEBUG_SYNC(thd, "before_close_thread_tables");
+#endif
+
   /* Detach MERGE children after every statement. Even under LOCK TABLES. */
   for (table= thd->open_tables; table; table= table->next)
   {
@@ -5293,7 +5299,7 @@ bool open_and_lock_tables(THD *thd, TABL
     tables	- list of tables for open
     flags       - bitmap of flags to modify how the tables will be open:
                   MYSQL_OPEN_IGNORE_FLUSH - open table even if someone has
-                  done a flush or namelock on it.
+                  done a flush on it.
 
   RETURN
     FALSE - ok
@@ -8851,8 +8857,57 @@ bool is_equal(const LEX_STRING *a, const
 
 
 /*
+  Unlock and close table before renaming and dropping partitions
+  SYNOPSIS
+    alter_close_tables()
+    lpt                        Struct carrying parameters
+  RETURN VALUES
+    0
+*/
+
+static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt)
+{
+  TABLE_SHARE *share= lpt->table->s;
+  THD *thd= lpt->thd;
+  TABLE *table;
+  DBUG_ENTER("alter_close_tables");
+  /*
+    We must keep LOCK_open while manipulating with thd->open_tables.
+    Another thread may be working on it.
+  */
+  mysql_mutex_lock(&LOCK_open);
+  /*
+    We can safely remove locks for all tables with the same name:
+    later they will all be closed anyway in
+    alter_partition_lock_handling().
+  */
+  for (table= thd->open_tables; table ; table= table->next)
+  {
+    if (!strcmp(table->s->table_name.str, share->table_name.str) &&
+	!strcmp(table->s->db.str, share->db.str))
+    {
+      mysql_lock_remove(thd, thd->lock, table);
+      table->file->close();
+      table->db_stat= 0;                        // Mark file closed
+      /*
+        Ensure that we won't end up with a crippled table instance
+        in the table cache if an error occurs before we reach
+        alter_partition_lock_handling() and the table is closed
+        by close_thread_tables() instead.
+      */
+      tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
+                       table->s->db.str,
+                       table->s->table_name.str);
+    }
+  }
+  mysql_mutex_unlock(&LOCK_open);
+  DBUG_RETURN(0);
+}
+
+
+/*
   SYNOPSIS
-    abort_and_upgrade_lock()
+    abort_and_upgrade_lock_and_close_table()
     lpt                           Parameter passing struct
     All parameters passed through the ALTER_PARTITION_PARAM_TYPE object
   RETURN VALUE
@@ -8861,7 +8916,7 @@ bool is_equal(const LEX_STRING *a, const
     Remember old lock level (for possible downgrade later on), abort all
     waiting threads and ensure that all keeping locks currently are
     completed such that we own the lock exclusively and no other interaction
-    is ongoing.
+    is ongoing. Close the table and hold the name lock.
 
     thd                           Thread object
     table                         Table object
@@ -8870,12 +8925,14 @@ bool is_equal(const LEX_STRING *a, const
     old_lock_level                Old lock level
 */
 
-int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt)
+int abort_and_upgrade_lock_and_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
 {
-  DBUG_ENTER("abort_and_upgrade_lock");
+  DBUG_ENTER("abort_and_upgrade_lock_and_close_table");
 
   if (wait_while_table_is_used(lpt->thd, lpt->table, HA_EXTRA_FORCE_REOPEN))
     DBUG_RETURN(1);
+  if (alter_close_tables(lpt))
+    DBUG_RETURN(1);
   DBUG_RETURN(0);
 }
 

=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h	2010-04-12 13:18:53 +0000
+++ b/sql/sql_base.h	2010-05-10 13:09:49 +0000
@@ -219,7 +219,7 @@ TABLE *open_n_lock_single_table(THD *thd
                                 thr_lock_type lock_type, uint flags);
 bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
 bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
-int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt);
+int abort_and_upgrade_lock_and_close_table(ALTER_PARTITION_PARAM_TYPE *lpt);
 int decide_logging_format(THD *thd, TABLE_LIST *tables);
 void free_io_cache(TABLE *entry);
 void intern_close_table(TABLE *entry);

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2010-04-15 12:51:12 +0000
+++ b/sql/sql_partition.cc	2010-05-10 13:09:49 +0000
@@ -6246,54 +6246,6 @@ static void alter_partition_lock_handlin
     sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
 }
 
-/*
-  Unlock and close table before renaming and dropping partitions
-  SYNOPSIS
-    alter_close_tables()
-    lpt                        Struct carrying parameters
-  RETURN VALUES
-    0
-*/
-
-static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt)
-{
-  TABLE_SHARE *share= lpt->table->s;
-  THD *thd= lpt->thd;
-  TABLE *table;
-  DBUG_ENTER("alter_close_tables");
-  /*
-    We must keep LOCK_open while manipulating with thd->open_tables.
-    Another thread may be working on it.
-  */
-  mysql_mutex_lock(&LOCK_open);
-  /*
-    We can safely remove locks for all tables with the same name:
-    later they will all be closed anyway in
-    alter_partition_lock_handling().
-  */
-  for (table= thd->open_tables; table ; table= table->next)
-  {
-    if (!strcmp(table->s->table_name.str, share->table_name.str) &&
-	!strcmp(table->s->db.str, share->db.str))
-    {
-      mysql_lock_remove(thd, thd->lock, table);
-      table->file->close();
-      table->db_stat= 0;                        // Mark file closed
-      /*
-        Ensure that we won't end up with a crippled table instance
-        in the table cache if an error occurs before we reach
-        alter_partition_lock_handling() and the table is closed
-        by close_thread_tables() instead.
-      */
-      tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
-                       table->s->db.str,
-                       table->s->table_name.str);
-    }
-  }
-  mysql_mutex_unlock(&LOCK_open);
-  DBUG_RETURN(0);
-}
-
 
 /*
   Handle errors for ALTER TABLE for partitioning
@@ -6592,9 +6544,7 @@ uint fast_alter_partition_table(THD *thd
         write_log_drop_partition(lpt) ||
         ERROR_INJECT_CRASH("crash_drop_partition_3") ||
         (not_completed= FALSE) ||
-        abort_and_upgrade_lock(lpt) ||
-        ERROR_INJECT_CRASH("crash_drop_partition_4") ||
-        alter_close_tables(lpt) ||
+        abort_and_upgrade_lock_and_close_table(lpt) ||
         ERROR_INJECT_CRASH("crash_drop_partition_5") ||
         ((!thd->lex->no_write_to_binlog) &&
          (write_bin_log(thd, FALSE,
@@ -6660,9 +6610,7 @@ uint fast_alter_partition_table(THD *thd
         ERROR_INJECT_CRASH("crash_add_partition_2") ||
         mysql_change_partitions(lpt) ||
         ERROR_INJECT_CRASH("crash_add_partition_3") ||
-        abort_and_upgrade_lock(lpt) ||
-        ERROR_INJECT_CRASH("crash_add_partition_4") ||
-        alter_close_tables(lpt) ||
+        abort_and_upgrade_lock_and_close_table(lpt) ||
         ERROR_INJECT_CRASH("crash_add_partition_5") ||
         ((!thd->lex->no_write_to_binlog) &&
          (write_bin_log(thd, FALSE,
@@ -6745,9 +6693,7 @@ uint fast_alter_partition_table(THD *thd
         write_log_final_change_partition(lpt) ||
         ERROR_INJECT_CRASH("crash_change_partition_4") ||
         (not_completed= FALSE) ||
-        abort_and_upgrade_lock(lpt) ||
-        ERROR_INJECT_CRASH("crash_change_partition_5") ||
-        alter_close_tables(lpt) ||
+        abort_and_upgrade_lock_and_close_table(lpt) ||
         ERROR_INJECT_CRASH("crash_change_partition_6") ||
         ((!thd->lex->no_write_to_binlog) &&
          (write_bin_log(thd, FALSE,

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2010-04-28 08:04:39 +0000
+++ b/sql/sql_show.cc	2010-05-10 13:09:49 +0000
@@ -50,7 +50,7 @@
 #endif
 #include <my_dir.h>
 #include "debug_sync.h"
-#include "lock.h"                           // MYSQL_LOCK_IGNORE_FLUSH
+#include "lock.h"                           // MYSQL_OPEN_IGNORE_FLUSH
 
 #define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
 
@@ -3674,6 +3674,7 @@ int get_all_tables(THD *thd, TABLE_LIST 
             lex->sql_command= SQLCOM_SHOW_FIELDS;
             show_table_list->i_s_requested_object=
               schema_table->i_s_requested_object;
+            DEBUG_SYNC(thd, "before_open_in_get_all_tables");
             res= open_normal_and_derived_tables(thd, show_table_list,
                    (MYSQL_OPEN_IGNORE_FLUSH |
                     MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |

=== modified file 'sql/tztime.cc'
--- a/sql/tztime.cc	2010-04-09 08:22:10 +0000
+++ b/sql/tztime.cc	2010-05-10 13:09:49 +0000
@@ -47,7 +47,7 @@
 #include <m_string.h>
 #include <my_dir.h>
 #include <mysql/psi/mysql_file.h>
-#include "lock.h"                               // MYSQL_LOCK_IGNORE_FLUSH,
+#include "lock.h"                               // MYSQL_OPEN_IGNORE_FLUSH,
                                                 // MYSQL_LOCK_IGNORE_TIMEOUT
 
 /*


Attachment: [text/bzr-bundle]
Thread
bzr commit into mysql-pe branch (mattias.jonsson:4065)Mattias Jonsson10 May