MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:October 18 2010 6:45am
Subject:bzr commit into mysql-next-mr-bugfixing branch (Li-Bing.Song:3324) Bug#55478
View as plain text  
#At file:///home/anders/work/bzrwork1/wt2/mysql-next-mr-bugfixing/ based on revid:dao-gang.qu@stripped

 3324 Li-Bing.Song@stripped	2010-10-18
      Bug#55478 Row events wrongly apply on the temporary table of the same name
      
      Rows events were applied wrongly on the temporary table with the same name.
      But rows events are generated only for base tables. As temporary
      table's data never be binlogged on row mode. Normally, base table of the
      same name cannot be updated if a temporary table has the same name.
      But there are two cases which can generate rows events on 
      the base table of same name.
      
      Case1: 'CREATE TABLE ... SELECT' statement.
      In mixed format, it will generate rows events if it is unsafe.
      
      Case2: Drop a transactional temporary table in a transaction.
      BEGIN;
      DROP TEMPORARY TABLE t1;       # t1 is a InnoDB table
      INSERT INTO t1 VALUES(rand()); # t1 is a MyISAM table
      COMMIT;
      'DROP TEMPORARY TABLE' will be put in the transaction cache and
      binlogged after the rows events generated by the 'INSERT' statement.
      
      After this patch, slave opens only base table when applying a rows event.

    modified:
      mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result
      mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test
      sql/log_event.cc
=== modified file 'mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result'
--- a/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result	2010-08-20 02:59:58 +0000
+++ b/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result	2010-10-18 06:45:28 +0000
@@ -65,9 +65,53 @@ slave-bin.000001	#	Query	#	#	use `test`;
 slave-bin.000001	#	Query	#	#	BEGIN
 slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
 slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
-slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Xid	#	#	COMMIT /* XID */
 slave-bin.000001	#	Query	#	#	use `test`; DROP TEMPORARY TABLE IF EXISTS `t2_tmp` /* generated by server */
 slave-bin.000001	#	Query	#	#	BEGIN
 slave-bin.000001	#	Query	#	#	use `test`; INSERT INTO t1 VALUES (2)
-slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Xid	#	#	COMMIT /* XID */
 slave-bin.000001	#	Query	#	#	use `test`; DROP TABLE `t3`,`t1` /* generated by server */
+
+# Bug#55478 Row events wrongly apply on the temporary table of the same name
+# ==========================================================================
+# The statement should be binlogged
+CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=InnoDB;
+
+# Case 1: CREATE TABLE t1 ... SELECT
+# ----------------------------------
+
+# The statement generates row events on t1. And the rows events should
+# be inserted into the base table on slave.
+CREATE TABLE t1 ENGINE=MyISAM SELECT rand();
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; CREATE TABLE `t1` (
+  `rand()` double NOT NULL DEFAULT '0'
+) ENGINE=MyISAM
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	COMMIT
+
+# Case 2: DROP TEMPORARY TABLE in a transacation
+# ----------------------------------------------
+
+BEGIN;
+DROP TEMPORARY TABLE t1;
+# The rows event will binlogged before 'DROP TEMPORARY TABLE t1',
+# as t1 is non-transactional table
+INSERT INTO t1 VALUES(Rand());
+COMMIT;
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; DROP TEMPORARY TABLE IF EXISTS `t1` /* generated by server */
+master-bin.000001	#	Query	#	#	COMMIT
+# Compare the base table.
+Comparing tables master:test.t1 and slave:test.t1
+
+DROP TABLE t1;

=== modified file 'mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test'
--- a/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test	2009-07-26 21:48:24 +0000
+++ b/mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test	2010-10-18 06:45:28 +0000
@@ -11,6 +11,7 @@
 
 source include/master-slave.inc;
 source include/have_binlog_format_mixed.inc;
+source include/have_innodb.inc;
 
 --echo ==== Initialize ====
 
@@ -146,3 +147,59 @@ DROP TABLE t3, t1;
 -- sync_slave_with_master
 
 -- source include/show_binlog_events.inc
+
+--echo
+--echo # Bug#55478 Row events wrongly apply on the temporary table of the same name
+--echo # ==========================================================================
+connection master;
+
+let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+--echo # The statement should be binlogged
+CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=InnoDB;
+
+--echo
+--echo # Case 1: CREATE TABLE t1 ... SELECT
+--echo # ----------------------------------
+let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+--echo
+--echo # The statement generates row events on t1. And the rows events should
+--echo # be inserted into the base table on slave.
+CREATE TABLE t1 ENGINE=MyISAM SELECT rand();
+
+source include/show_binlog_events.inc;
+let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+--echo
+--echo # Case 2: DROP TEMPORARY TABLE in a transacation
+--echo # ----------------------------------------------
+--echo
+
+BEGIN;
+DROP TEMPORARY TABLE t1;
+
+# The patch for BUG#55478 fixed the problem only on RBR. The problem on SBR
+# will be fixed by the patch for bug#55709. So This statement cannot be
+# executed until Bug#55709 is fixed
+#
+# INSERT INTO t1 VALUES(1);
+
+--echo # The rows event will binlogged before 'DROP TEMPORARY TABLE t1',
+--echo # as t1 is non-transactional table
+INSERT INTO t1 VALUES(Rand());
+COMMIT;
+
+source include/show_binlog_events.inc;
+
+--echo # Compare the base table.
+let diff_table= test.t1;
+source include/rpl_diff_tables.inc;
+
+--echo
+connection master;
+DROP TABLE t1;
+source include/master-slave-end.inc;

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-09-24 15:24:54 +0000
+++ b/sql/log_event.cc	2010-10-18 06:45:28 +0000
@@ -8439,6 +8439,7 @@ int Table_map_log_event::do_apply_event(
                 m_field_metadata, m_field_metadata_size,
                 m_null_bits, m_flags);
     table_list->m_tabledef_valid= TRUE;
+    table_list->open_type= OT_BASE_ONLY;
 
     /*
       We record in the slave's information that the table should be


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20101018064528-vbl57bd4ciihghwx.bundle
Thread
bzr commit into mysql-next-mr-bugfixing branch (Li-Bing.Song:3324) Bug#55478Li-Bing.Song18 Oct