List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:October 13 2010 3:40am
Subject:bzr commit into mysql-trunk-merge branch (Li-Bing.Song:3266)
View as plain text  
#At file:///home/anders/work/bzrwork1/wt5/mysql-trunk-merge/ based on revid:dmitry.shulga@stripped

 3266 Li-Bing.Song@stripped	2010-10-13 [merge]
      Auto merge

    added:
      mysql-test/extra/rpl_tests/rpl_stop_slave.test
      mysql-test/suite/rpl/r/rpl_stop_slave.result
      mysql-test/suite/rpl/t/rpl_stop_slave.test
    modified:
      sql/rpl_slave.cc
      sql/sql_parse.cc
=== added file 'mysql-test/extra/rpl_tests/rpl_stop_slave.test'
--- a/mysql-test/extra/rpl_tests/rpl_stop_slave.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_stop_slave.test	2010-10-13 03:19:20 +0000
@@ -0,0 +1,61 @@
+#
+# Auxiliary file which is used to test BUG#56118 
+#
+# Slave should apply all statements in the transaction before stop if any
+# temporary table is created or dropped.
+#
+# USEAGE: 
+# --let $tmp_table_stm= a SQL statement 
+# --source extra/rpl_tests/rpl_stop_slave.test
+#
+
+if (`SELECT "$tmp_table_stm" = ''`)
+{
+  --echo \$tmp_table_stm is NULL
+  --die $tmp_table_stm is NULL
+}
+
+--echo
+--echo [ On Master ]
+connection master;
+BEGIN;
+DELETE FROM t1;
+eval $tmp_table_stm;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE tt1;
+COMMIT;
+
+--echo
+--echo [ On Slave ]
+connection slave;
+
+# To check if slave SQL thread is applying INSERT statement
+let $show_statement= SHOW PROCESSLIST;
+let $field= Info;
+let $condition= LIKE 'INSERT%';
+source include/wait_show_condition.inc;
+
+send STOP SLAVE SQL_THREAD;
+
+--echo
+--echo [ On Slave1 ]
+connection slave1;
+--echo # To resume slave SQL thread
+SET DEBUG_SYNC= 'now SIGNAL signal.continue';
+SET DEBUG_SYNC= 'RESET';
+
+--echo
+--echo [ On Slave ]
+connection slave;
+reap;
+source include/wait_for_slave_sql_to_stop.inc;
+
+--echo # Slave should stop after the transaction has committed.
+--echo # So t1 on master is same to t1 on slave.
+let diff_table_1=master:test.t1;
+let diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+connection slave;
+START SLAVE SQL_THREAD;
+source include/wait_for_slave_sql_to_start.inc;

=== added file 'mysql-test/suite/rpl/r/rpl_stop_slave.result'
--- a/mysql-test/suite/rpl/r/rpl_stop_slave.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stop_slave.result	2010-10-13 03:19:20 +0000
@@ -0,0 +1,127 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+
+# BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends
+#
+# If a temporary table is created or dropped, the transaction should be
+# regarded similarly that a non-transactional table is modified. So 
+# STOP SLAVE should wait until the transaction has finished.
+CREATE TABLE t1(c1 INT) ENGINE=InnoDB;
+CREATE TABLE t2(c1 INT) ENGINE=InnoDB;
+SET DEBUG_SYNC= 'RESET';
+include/stop_slave.inc
+
+# Suspend the INSERT statement in current transaction on SQL thread.
+# It guarantees that SQL thread is applying the transaction when
+# STOP SLAVE command launchs.
+SET GLOBAL debug= 'd,after_mysql_insert';
+include/start_slave.inc
+
+# CREATE TEMPORARY TABLE with InnoDB engine
+# -----------------------------------------
+
+[ On Master ]
+BEGIN;
+DELETE FROM t1;
+CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE tt1;
+COMMIT;
+
+[ On Slave ]
+STOP SLAVE SQL_THREAD;
+
+[ On Slave1 ]
+# To resume slave SQL thread
+SET DEBUG_SYNC= 'now SIGNAL signal.continue';
+SET DEBUG_SYNC= 'RESET';
+
+[ On Slave ]
+# Slave should stop after the transaction has committed.
+# So t1 on master is same to t1 on slave.
+Comparing tables master:test.t1 and slave:test.t1
+START SLAVE SQL_THREAD;
+
+# CREATE TEMPORARY TABLE with MyISAM engine
+# -----------------------------------------
+
+[ On Master ]
+BEGIN;
+DELETE FROM t1;
+CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE tt1;
+COMMIT;
+
+[ On Slave ]
+STOP SLAVE SQL_THREAD;
+
+[ On Slave1 ]
+# To resume slave SQL thread
+SET DEBUG_SYNC= 'now SIGNAL signal.continue';
+SET DEBUG_SYNC= 'RESET';
+
+[ On Slave ]
+# Slave should stop after the transaction has committed.
+# So t1 on master is same to t1 on slave.
+Comparing tables master:test.t1 and slave:test.t1
+START SLAVE SQL_THREAD;
+
+# CREATE TEMPORARY TABLE ... SELECT with InnoDB engine
+# ----------------------------------------------------
+
+[ On Master ]
+BEGIN;
+DELETE FROM t1;
+CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB
+SELECT c1 FROM t2;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE tt1;
+COMMIT;
+
+[ On Slave ]
+STOP SLAVE SQL_THREAD;
+
+[ On Slave1 ]
+# To resume slave SQL thread
+SET DEBUG_SYNC= 'now SIGNAL signal.continue';
+SET DEBUG_SYNC= 'RESET';
+
+[ On Slave ]
+# Slave should stop after the transaction has committed.
+# So t1 on master is same to t1 on slave.
+Comparing tables master:test.t1 and slave:test.t1
+START SLAVE SQL_THREAD;
+
+# CREATE TEMPORARY TABLE ... SELECT with MyISAM engine
+# ----------------------------------------------------
+
+[ On Master ]
+BEGIN;
+DELETE FROM t1;
+CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM
+SELECT 1 AS c1;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE tt1;
+COMMIT;
+
+[ On Slave ]
+STOP SLAVE SQL_THREAD;
+
+[ On Slave1 ]
+# To resume slave SQL thread
+SET DEBUG_SYNC= 'now SIGNAL signal.continue';
+SET DEBUG_SYNC= 'RESET';
+
+[ On Slave ]
+# Slave should stop after the transaction has committed.
+# So t1 on master is same to t1 on slave.
+Comparing tables master:test.t1 and slave:test.t1
+START SLAVE SQL_THREAD;
+# Test end
+SET GLOBAL debug= '$debug_save';
+DROP TABLE t1, t2;

=== added file 'mysql-test/suite/rpl/t/rpl_stop_slave.test'
--- a/mysql-test/suite/rpl/t/rpl_stop_slave.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stop_slave.test	2010-10-13 03:19:20 +0000
@@ -0,0 +1,60 @@
+source include/master-slave.inc;
+source include/have_innodb.inc;
+source include/have_debug.inc;
+source include/have_debug_sync.inc;
+source include/have_binlog_format_mixed_or_statement.inc;
+
+--echo
+--echo # BUG#56118 STOP SLAVE does not wait till trx with CREATE TMP TABLE ends
+--echo #
+--echo # If a temporary table is created or dropped, the transaction should be
+--echo # regarded similarly that a non-transactional table is modified. So 
+--echo # STOP SLAVE should wait until the transaction has finished.
+
+CREATE TABLE t1(c1 INT) ENGINE=InnoDB;
+CREATE TABLE t2(c1 INT) ENGINE=InnoDB;
+
+sync_slave_with_master;
+SET DEBUG_SYNC= 'RESET';
+source include/stop_slave.inc;
+
+--echo
+--echo # Suspend the INSERT statement in current transaction on SQL thread.
+--echo # It guarantees that SQL thread is applying the transaction when
+--echo # STOP SLAVE command launchs.
+let $debug_save= `SELECT @@GLOBAL.debug`;
+SET GLOBAL debug= 'd,after_mysql_insert';
+source include/start_slave.inc;
+
+--echo
+--echo # CREATE TEMPORARY TABLE with InnoDB engine
+--echo # -----------------------------------------
+let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB;
+source extra/rpl_tests/rpl_stop_slave.test;
+
+--echo
+--echo # CREATE TEMPORARY TABLE with MyISAM engine
+--echo # -----------------------------------------
+let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM;
+source extra/rpl_tests/rpl_stop_slave.test;
+
+--echo
+--echo # CREATE TEMPORARY TABLE ... SELECT with InnoDB engine
+--echo # ----------------------------------------------------
+let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = InnoDB
+                    SELECT c1 FROM t2;
+source extra/rpl_tests/rpl_stop_slave.test;
+
+--echo
+--echo # CREATE TEMPORARY TABLE ... SELECT with MyISAM engine
+--echo # ----------------------------------------------------
+let $tmp_table_stm= CREATE TEMPORARY TABLE tt1(c1 INT) ENGINE = MyISAM
+                    SELECT 1 AS c1;
+source extra/rpl_tests/rpl_stop_slave.test;
+
+--echo # Test end
+SET GLOBAL debug= '$debug_save';
+
+connection master;
+DROP TABLE t1, t2;
+source include/master-slave-end.inc;

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2010-10-09 10:25:01 +0000
+++ b/sql/rpl_slave.cc	2010-10-13 03:39:19 +0000
@@ -881,7 +881,17 @@ static bool sql_slave_killed(THD* thd, R
   DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
   if (abort_loop || thd->killed || rli->abort_slave)
   {
-    if (thd->transaction.all.modified_non_trans_table && rli->is_in_group())
+    /*
+      The transaction should always be binlogged if OPTION_KEEP_LOG is set
+      (it implies that something can not be rolled back). And such case
+      should be regarded similarly as modifing a non-transactional table
+      because retrying of the transaction will lead to an error or inconsistency
+      as well.
+      Example: OPTION_KEEP_LOG is set if a temporary table is created or dropped.
+    */
+    if ((thd->transaction.all.modified_non_trans_table ||
+         (thd->variables.option_bits & OPTION_KEEP_LOG))
+        && rli->is_in_group())
     {
       char msg_stopped[]=
         "... The slave SQL is stopped, leaving the current group "

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-10-07 12:47:15 +0000
+++ b/sql/sql_parse.cc	2010-10-13 03:39:19 +0000
@@ -2824,6 +2824,15 @@ end_with_restore_list:
       thd->first_successful_insert_id_in_cur_stmt=
         thd->first_successful_insert_id_in_prev_stmt;
 
+    DBUG_EXECUTE_IF("after_mysql_insert",
+                    {
+                      const char act[]=
+                        "now "
+                        "wait_for signal.continue";
+                      DBUG_ASSERT(opt_debug_sync_timeout > 0);
+                      DBUG_ASSERT(!debug_sync_set_action(current_thd,
+                                                         STRING_WITH_LEN(act)));
+                    };);
     break;
   }
   case SQLCOM_REPLACE_SELECT:


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20101013033919-0eh1is177s9aild8.bundle
Thread
bzr commit into mysql-trunk-merge branch (Li-Bing.Song:3266) Li-Bing.Song13 Oct