List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:December 20 2007 2:24pm
Subject:bk commit into 5.0 tree (mats:1.2557) BUG#12691
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of mats. When mats does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-12-20 15:24:27+01:00, mats@stripped +3 -0
  BUG#12691 (Exec_master_log_pos corrupted with SQL_SLAVE_SKIP_COUNTER):
  
  Complementary patch since LOAD DATA INFILE was not covered in
  the previous patch.
  
  This patch adds a check so that the slave skip counter is not
  decreased to zero if seeing a BEGIN_LOAD_QUERY_EVENT,
  APPEND_BLOCK_EVENT, or CREATE_FILE_EVENT since these cannot
  end a group. The group is terminated by an EXECUTE_LOAD_QUERY_
  EVENT or DELETE_FILE_EVENT.

  mysql-test/r/rpl_slave_skip.result@stripped, 2007-12-20 15:24:24+01:00, mats@stripped +158 -3
    Result change.

  mysql-test/t/rpl_slave_skip.test@stripped, 2007-12-20 15:24:25+01:00, mats@stripped +134 -3
    Adding tests to test that the first event of a LOAD DATA INFILE
    can be skipped safely for both transactional and non-transactional
    tables. 

  sql/slave.cc@stripped, 2007-12-20 15:24:25+01:00, mats@stripped +4 -1
    Not decrementing slave skip counter to zero when seeing a
    BEGIN_LOAD_QUERY_EVENT, APPEND_BLOCK_EVENT, or CREATE_FILE_EVENT
    since these cannot end a group.

diff -Nrup a/mysql-test/r/rpl_slave_skip.result b/mysql-test/r/rpl_slave_skip.result
--- a/mysql-test/r/rpl_slave_skip.result	2007-10-26 18:52:53 +02:00
+++ b/mysql-test/r/rpl_slave_skip.result	2007-12-20 15:24:24 +01:00
@@ -5,8 +5,10 @@ reset slave;
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 start slave;
 **** On Master ****
-CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=INNODB;
-CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MYISAM;
+CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MyISAM;
+CREATE TABLE t3 (a CHAR(20), b SET('master','slave')) ENGINE=InnoDB;
+CREATE TABLE t4 (a CHAR(20), b SET('master','slave')) ENGINE=MyISAM;
 ==== Skipping normal transactions ==== 
 **** On Slave ****
 STOP SLAVE;
@@ -139,6 +141,159 @@ a	b
 SELECT * FROM t2 ORDER BY a;
 a	b
 5	master,slave
+==== Skipping first event of a LOAD DATA for a transactional table ==== 
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+SET AUTOCOMMIT=1;
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t3(a) SET b = 'master';
+INSERT INTO t3 VALUES ('Go Rin No Sho', 'master,slave');
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+71
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+-- Should only contain records marked 'master,slave'
+SELECT * FROM t3 ORDER BY a;
+a	b
+Go Rin No Sho	master,slave
+**** On Master ****
+DELETE FROM t3;
+==== Skipping first event of a LOAD DATA for a non-transactional table ==== 
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+SET AUTOCOMMIT=1;
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave');
+SELECT COUNT(*) FROM t4;
+COUNT(*)
+71
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+-- Should only contain records marked 'master,slave'
+SELECT * FROM t4 ORDER BY a;
+a	b
+Go Rin No Sho	master,slave
+**** On Master ****
+DELETE FROM t4;
+==== Try with a big file so that we get an append_block event as well
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+SET AUTOCOMMIT=1;
+SET SQL_LOG_BIN=0;
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+SELECT a FROM t4 INTO OUTFILE 'rpl_slave_skip_words.dat';
+SET SQL_LOG_BIN=1;
+LOAD DATA INFILE 'rpl_slave_skip_words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave');
+SHOW BINLOG EVENTS;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	98	Server ver: 5.0.52-debug-log, Binlog ver: 4
+master-bin.000001	98	Query	1	223	use `test`; CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=InnoDB
+master-bin.000001	223	Query	1	348	use `test`; CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MyISAM
+master-bin.000001	348	Query	1	478	use `test`; CREATE TABLE t3 (a CHAR(20), b SET('master','slave')) ENGINE=InnoDB
+master-bin.000001	478	Query	1	608	use `test`; CREATE TABLE t4 (a CHAR(20), b SET('master','slave')) ENGINE=MyISAM
+master-bin.000001	608	Query	1	676	use `test`; BEGIN
+master-bin.000001	676	Query	1	774	use `test`; INSERT INTO t1 VALUES (1, 'master')
+master-bin.000001	774	Query	1	872	use `test`; INSERT INTO t1 VALUES (2, 'master')
+master-bin.000001	872	Query	1	970	use `test`; INSERT INTO t1 VALUES (3, 'master')
+master-bin.000001	970	Xid	1	997	COMMIT /* xid=16 */
+master-bin.000001	997	Query	1	1065	use `test`; BEGIN
+master-bin.000001	1065	Query	1	1169	use `test`; INSERT INTO t1 VALUES (4, 'master,slave')
+master-bin.000001	1169	Query	1	1273	use `test`; INSERT INTO t1 VALUES (5, 'master,slave')
+master-bin.000001	1273	Query	1	1377	use `test`; INSERT INTO t1 VALUES (6, 'master,slave')
+master-bin.000001	1377	Xid	1	1404	COMMIT /* xid=21 */
+master-bin.000001	1404	Query	1	1481	use `test`; DELETE FROM t1
+master-bin.000001	1481	Xid	1	1508	COMMIT /* xid=31 */
+master-bin.000001	1508	Query	1	1576	use `test`; BEGIN
+master-bin.000001	1576	Query	1	1674	use `test`; INSERT INTO t1 VALUES (1, 'master')
+master-bin.000001	1674	Query	1	1772	use `test`; INSERT INTO t1 VALUES (2, 'master')
+master-bin.000001	1772	Query	1	1870	use `test`; INSERT INTO t1 VALUES (3, 'master')
+master-bin.000001	1870	Xid	1	1897	COMMIT /* xid=34 */
+master-bin.000001	1897	Query	1	1965	use `test`; BEGIN
+master-bin.000001	1965	Query	1	2063	use `test`; INSERT INTO t1 VALUES (4, 'master')
+master-bin.000001	2063	Query	1	2161	use `test`; INSERT INTO t1 VALUES (5, 'master')
+master-bin.000001	2161	Query	1	2259	use `test`; INSERT INTO t1 VALUES (6, 'master')
+master-bin.000001	2259	Xid	1	2286	COMMIT /* xid=39 */
+master-bin.000001	2286	Query	1	2354	use `test`; BEGIN
+master-bin.000001	2354	Query	1	2458	use `test`; INSERT INTO t1 VALUES (7, 'master,slave')
+master-bin.000001	2458	Query	1	2562	use `test`; INSERT INTO t1 VALUES (8, 'master,slave')
+master-bin.000001	2562	Query	1	2666	use `test`; INSERT INTO t1 VALUES (9, 'master,slave')
+master-bin.000001	2666	Xid	1	2693	COMMIT /* xid=44 */
+master-bin.000001	2693	Query	1	2770	use `test`; DELETE FROM t1
+master-bin.000001	2770	Xid	1	2797	COMMIT /* xid=54 */
+master-bin.000001	2797	Query	1	2865	use `test`; BEGIN
+master-bin.000001	2865	Query	1	2963	use `test`; INSERT INTO t1 VALUES (1, 'master')
+master-bin.000001	2963	Query	1	3061	use `test`; INSERT INTO t1 VALUES (2, 'master')
+master-bin.000001	3061	Query	1	3159	use `test`; INSERT INTO t1 VALUES (3, 'master')
+master-bin.000001	3159	Xid	1	3186	COMMIT /* xid=57 */
+master-bin.000001	3186	Query	1	3254	use `test`; BEGIN
+master-bin.000001	3254	Query	1	3358	use `test`; INSERT INTO t1 VALUES (4, 'master,slave')
+master-bin.000001	3358	Query	1	3462	use `test`; INSERT INTO t1 VALUES (5, 'master,slave')
+master-bin.000001	3462	Query	1	3566	use `test`; INSERT INTO t1 VALUES (6, 'master,slave')
+master-bin.000001	3566	Xid	1	3593	COMMIT /* xid=61 */
+master-bin.000001	3593	Query	1	3670	use `test`; DELETE FROM t1
+master-bin.000001	3670	Xid	1	3697	COMMIT /* xid=66 */
+master-bin.000001	3697	Query	1	3765	use `test`; BEGIN
+master-bin.000001	3765	Query	1	3857	use `test`; INSERT INTO t1 VALUES (1, '')
+master-bin.000001	3857	Query	1	3955	use `test`; INSERT INTO t2 VALUES (2, 'master')
+master-bin.000001	3955	Query	1	4047	use `test`; INSERT INTO t1 VALUES (3, '')
+master-bin.000001	4047	Query	1	4118	use `test`; ROLLBACK
+master-bin.000001	4118	Query	1	4186	use `test`; BEGIN
+master-bin.000001	4186	Query	1	4278	use `test`; INSERT INTO t1 VALUES (4, '')
+master-bin.000001	4278	Query	1	4382	use `test`; INSERT INTO t2 VALUES (5, 'master,slave')
+master-bin.000001	4382	Query	1	4474	use `test`; INSERT INTO t1 VALUES (6, '')
+master-bin.000001	4474	Query	1	4545	use `test`; ROLLBACK
+master-bin.000001	4545	Begin_load_query	1	5149	;file_id=1;block_len=581
+master-bin.000001	5149	Execute_load_query	1	5302	use `test`; LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t3(a) SET b = 'master' ;file_id=1
+master-bin.000001	5302	Xid	1	5329	COMMIT /* xid=92 */
+master-bin.000001	5329	Query	1	5447	use `test`; INSERT INTO t3 VALUES ('Go Rin No Sho', 'master,slave')
+master-bin.000001	5447	Xid	1	5474	COMMIT /* xid=93 */
+master-bin.000001	5474	Query	1	5551	use `test`; DELETE FROM t3
+master-bin.000001	5551	Xid	1	5578	COMMIT /* xid=100 */
+master-bin.000001	5578	Begin_load_query	1	6182	;file_id=2;block_len=581
+master-bin.000001	6182	Execute_load_query	1	6335	use `test`; LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master' ;file_id=2
+master-bin.000001	6335	Query	1	6453	use `test`; INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave')
+master-bin.000001	6453	Query	1	6530	use `test`; DELETE FROM t4
+master-bin.000001	6530	Begin_load_query	1	137625	;file_id=4;block_len=131072
+master-bin.000001	137625	Append_block	1	268720	;file_id=4;block_len=131072
+master-bin.000001	268720	Append_block	1	399815	;file_id=4;block_len=131072
+master-bin.000001	399815	Append_block	1	530910	;file_id=4;block_len=131072
+master-bin.000001	530910	Append_block	1	662005	;file_id=4;block_len=131072
+master-bin.000001	662005	Append_block	1	793100	;file_id=4;block_len=131072
+master-bin.000001	793100	Append_block	1	924195	;file_id=4;block_len=131072
+master-bin.000001	924195	Append_block	1	1055290	;file_id=4;block_len=131072
+master-bin.000001	1055290	Append_block	1	1186385	;file_id=4;block_len=131072
+master-bin.000001	1186385	Append_block	1	1196648	;file_id=4;block_len=10240
+master-bin.000001	1196648	Execute_load_query	1	1196801	use `test`; LOAD DATA INFILE 'rpl_slave_skip_words.dat' INTO TABLE t4(a) SET b = 'master' ;file_id=4
+master-bin.000001	1196801	Query	1	1196919	use `test`; INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave')
+SELECT COUNT(*) FROM t4;
+COUNT(*)
+286721
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+-- Should only contain records marked 'master,slave'
+SELECT * FROM t4 ORDER BY a;
+a	b
+Go Rin No Sho	master,slave
+**** On Master ****
+DELETE FROM t4;
 ==== Cleanup ==== 
 **** On Master ****
-DROP TABLE t1, t2;
+DROP TABLE t1, t2, t3, t4;
diff -Nrup a/mysql-test/t/rpl_slave_skip.test b/mysql-test/t/rpl_slave_skip.test
--- a/mysql-test/t/rpl_slave_skip.test	2007-10-26 18:52:54 +02:00
+++ b/mysql-test/t/rpl_slave_skip.test	2007-12-20 15:24:25 +01:00
@@ -1,4 +1,5 @@
 source include/have_innodb.inc;
+source include/have_debug.inc;
 source include/master-slave.inc;
 
 # This test is for checking that the use of SQL_SLAVE_SKIP_COUNTER
@@ -13,8 +14,10 @@ source include/master-slave.inc;
 # it back to get the non-transactional change into the table.
 
 --echo **** On Master ****
-CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=INNODB;
-CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MYISAM;
+CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MyISAM;
+CREATE TABLE t3 (a CHAR(20), b SET('master','slave')) ENGINE=InnoDB;
+CREATE TABLE t4 (a CHAR(20), b SET('master','slave')) ENGINE=MyISAM;
 
 --echo ==== Skipping normal transactions ==== 
 
@@ -195,9 +198,137 @@ sync_with_master;
 SELECT * FROM t1 ORDER BY a;
 SELECT * FROM t2 ORDER BY a;
 
+--echo ==== Skipping first event of a LOAD DATA for a transactional table ==== 
+
+--echo **** On Slave ****
+connection slave;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+SET AUTOCOMMIT=1;
+
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t3(a) SET b = 'master';
+INSERT INTO t3 VALUES ('Go Rin No Sho', 'master,slave');
+
+save_master_pos;
+
+SELECT COUNT(*) FROM t3;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+--echo -- Should only contain records marked 'master,slave'
+SELECT * FROM t3 ORDER BY a;
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t3;
+sync_slave_with_master;
+
+--echo ==== Skipping first event of a LOAD DATA for a non-transactional table ==== 
+
+--echo **** On Slave ****
+connection slave;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+SET AUTOCOMMIT=1;
+
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave');
+
+save_master_pos;
+
+SELECT COUNT(*) FROM t4;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+--echo -- Should only contain records marked 'master,slave'
+SELECT * FROM t4 ORDER BY a;
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t4;
+sync_slave_with_master;
+
+--echo ==== Try with a big file so that we get an append_block event as well
+
+--echo **** On Slave ****
+connection slave;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+SET AUTOCOMMIT=1;
+
+# This contain about 70 words, so we double it a few times to get more than 128 KiB
+SET SQL_LOG_BIN=0;
+LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+INSERT INTO t4 SELECT * FROM t4;
+SELECT a FROM t4 INTO OUTFILE 'rpl_slave_skip_words.dat';
+SET SQL_LOG_BIN=1;
+
+# Start the real job
+LOAD DATA INFILE 'rpl_slave_skip_words.dat' INTO TABLE t4(a) SET b = 'master';
+INSERT INTO t4 VALUES ('Go Rin No Sho', 'master,slave');
+
+SHOW BINLOG EVENTS;
+
+save_master_pos;
+
+SELECT COUNT(*) FROM t4;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+--echo -- Should only contain records marked 'master,slave'
+SELECT * FROM t4 ORDER BY a;
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t4;
+sync_slave_with_master;
+
 --echo ==== Cleanup ==== 
 
 --echo **** On Master ****
 connection master;
-DROP TABLE t1, t2;
+DROP TABLE t1, t2, t3, t4;
 sync_slave_with_master;
diff -Nrup a/sql/slave.cc b/sql/slave.cc
--- a/sql/slave.cc	2007-10-26 19:17:55 +02:00
+++ b/sql/slave.cc	2007-12-20 15:24:25 +01:00
@@ -3348,7 +3348,10 @@ static int exec_relay_log_event(THD* thd
       if (rli->slave_skip_counter &&
           !((type_code == INTVAR_EVENT ||
              type_code == RAND_EVENT ||
-             type_code == USER_VAR_EVENT) &&
+             type_code == USER_VAR_EVENT ||
+             type_code == BEGIN_LOAD_QUERY_EVENT ||
+             type_code == APPEND_BLOCK_EVENT ||
+             type_code == CREATE_FILE_EVENT) &&
             rli->slave_skip_counter == 1) &&
 #if MYSQL_VERSION_ID < 50100
           /*
Thread
bk commit into 5.0 tree (mats:1.2557) BUG#12691Mats Kindahl30 Dec