mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
BUG#28618 (Skipping into the middle of a group with SQL_SLAVE_SKIP_COUNTER
is possible): When skipping the beginning of a transaction starting with BEGIN, the OPTION_BEGIN flag was not set correctly, which caused the slave to not recognize that it was inside a group. This patch sets the OPTION_BEGIN flag for BEGIN, COMMIT, ROLLBACK, and XID events. It also adds checks if inside a group before decreasing the slave skip counter to zero. Begin_query_log_event was not marked that it could not end a group, which is now corrected.
This commit is contained in:
@ -736,7 +736,7 @@ connection slave;
|
||||
--replace_result $MASTER_MYPORT MASTER_PORT
|
||||
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
|
||||
--query_vertical SHOW SLAVE STATUS
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
|
||||
--echo *** Try to insert in master ****
|
||||
@ -744,6 +744,8 @@ connection master;
|
||||
INSERT INTO t15 () VALUES(5,2.00,'Replication Testing',@b1,'Buda',2);
|
||||
SELECT * FROM t15 ORDER BY c1;
|
||||
|
||||
#SHOW BINLOG EVENTS;
|
||||
|
||||
--echo *** Try to select from slave ****
|
||||
sync_slave_with_master;
|
||||
--replace_column 7 CURRENT_TIMESTAMP
|
||||
|
3
mysql-test/suite/rpl/data/rpl_bug28618.dat
Normal file
3
mysql-test/suite/rpl/data/rpl_bug28618.dat
Normal file
@ -0,0 +1,3 @@
|
||||
1|master only
|
||||
2|master only
|
||||
3|master only
|
@ -142,3 +142,211 @@ Last_SQL_Errno 0
|
||||
Last_SQL_Error
|
||||
**** On Master ****
|
||||
DROP TABLE t1, t2;
|
||||
SET SESSION BINLOG_FORMAT=ROW;
|
||||
SET AUTOCOMMIT=0;
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(20)) ENGINE=myisam;
|
||||
CREATE TABLE t2 (a INT, b VARCHAR(20)) ENGINE=myisam;
|
||||
CREATE TABLE t3 (a INT, b VARCHAR(20)) ENGINE=myisam;
|
||||
INSERT INTO t1 VALUES (1,'master/slave');
|
||||
INSERT INTO t2 VALUES (1,'master/slave');
|
||||
INSERT INTO t3 VALUES (1,'master/slave');
|
||||
CREATE TRIGGER tr1 AFTER UPDATE on t1 FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO t2 VALUES (NEW.a,NEW.b);
|
||||
DELETE FROM t2 WHERE a < NEW.a;
|
||||
END|
|
||||
CREATE TRIGGER tr2 AFTER INSERT on t2 FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE t3 SET a =2, b = 'master only';
|
||||
END|
|
||||
**** On Slave ****
|
||||
STOP SLAVE;
|
||||
**** On Master ****
|
||||
UPDATE t1 SET a = 2, b = 'master only' WHERE a = 1;
|
||||
DROP TRIGGER tr1;
|
||||
DROP TRIGGER tr2;
|
||||
INSERT INTO t1 VALUES (3,'master/slave');
|
||||
INSERT INTO t2 VALUES (3,'master/slave');
|
||||
INSERT INTO t3 VALUES (3,'master/slave');
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
SELECT * FROM t3 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
*** On Slave ***
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
1 master/slave
|
||||
3 master/slave
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
a b
|
||||
1 master/slave
|
||||
3 master/slave
|
||||
SELECT * FROM t3 ORDER BY a;
|
||||
a b
|
||||
1 master/slave
|
||||
3 master/slave
|
||||
DROP TABLE t1, t2, t3;
|
||||
**** Case 2: Row binlog format and transactional tables ****
|
||||
*** On Master ***
|
||||
CREATE TABLE t4 (a INT, b VARCHAR(20)) ENGINE=innodb;
|
||||
CREATE TABLE t5 (a INT, b VARCHAR(20)) ENGINE=innodb;
|
||||
CREATE TABLE t6 (a INT, b VARCHAR(20)) ENGINE=innodb;
|
||||
**** On Slave ****
|
||||
STOP SLAVE;
|
||||
*** On Master ***
|
||||
BEGIN;
|
||||
INSERT INTO t4 VALUES (2, 'master only');
|
||||
INSERT INTO t5 VALUES (2, 'master only');
|
||||
INSERT INTO t6 VALUES (2, 'master only');
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
INSERT INTO t4 VALUES (3, 'master/slave');
|
||||
INSERT INTO t5 VALUES (3, 'master/slave');
|
||||
INSERT INTO t6 VALUES (3, 'master/slave');
|
||||
COMMIT;
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
*** On Slave ***
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
**** On Slave ****
|
||||
STOP SLAVE;
|
||||
*** On Master ***
|
||||
BEGIN;
|
||||
INSERT INTO t4 VALUES (6, 'master only');
|
||||
INSERT INTO t5 VALUES (6, 'master only');
|
||||
INSERT INTO t6 VALUES (6, 'master only');
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
INSERT INTO t4 VALUES (7, 'master only');
|
||||
INSERT INTO t5 VALUES (7, 'master only');
|
||||
INSERT INTO t6 VALUES (7, 'master only');
|
||||
COMMIT;
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
6 master only
|
||||
7 master only
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
6 master only
|
||||
7 master only
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
6 master only
|
||||
7 master only
|
||||
*** On Slave ***
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=10;
|
||||
START SLAVE;
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
STOP SLAVE;
|
||||
SET AUTOCOMMIT=0;
|
||||
INSERT INTO t4 VALUES (4, 'master only');
|
||||
INSERT INTO t5 VALUES (4, 'master only');
|
||||
INSERT INTO t6 VALUES (4, 'master only');
|
||||
COMMIT;
|
||||
INSERT INTO t4 VALUES (5, 'master/slave');
|
||||
INSERT INTO t5 VALUES (5, 'master/slave');
|
||||
INSERT INTO t6 VALUES (5, 'master/slave');
|
||||
COMMIT;
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
4 master only
|
||||
5 master/slave
|
||||
6 master only
|
||||
7 master only
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
4 master only
|
||||
5 master/slave
|
||||
6 master only
|
||||
7 master only
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
a b
|
||||
2 master only
|
||||
3 master/slave
|
||||
4 master only
|
||||
5 master/slave
|
||||
6 master only
|
||||
7 master only
|
||||
*** On Slave ***
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
5 master/slave
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
5 master/slave
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
a b
|
||||
3 master/slave
|
||||
5 master/slave
|
||||
DROP TABLE t4, t5, t6;
|
||||
**** Case 3: Statement logging format and LOAD DATA with non-transactional table ****
|
||||
*** On Master ***
|
||||
CREATE TABLE t10 (a INT, b VARCHAR(20)) ENGINE=myisam;
|
||||
*** On Slave ***
|
||||
STOP SLAVE;
|
||||
*** On Master ***
|
||||
SET SESSION BINLOG_FORMAT=STATEMENT;
|
||||
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/rpl_bug28618.dat' INTO TABLE t10 FIELDS TERMINATED BY '|';
|
||||
SELECT * FROM t10 ORDER BY a;
|
||||
a b
|
||||
1 master only
|
||||
2 master only
|
||||
3 master only
|
||||
*** On Slave ***
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
SELECT * FROM t10 ORDER BY a;
|
||||
a b
|
||||
DROP TABLE t10;
|
||||
|
1
mysql-test/suite/rpl/t/rpl_slave_skip-slave.opt
Normal file
1
mysql-test/suite/rpl/t/rpl_slave_skip-slave.opt
Normal file
@ -0,0 +1 @@
|
||||
--innodb
|
@ -1,7 +1,9 @@
|
||||
source include/master-slave.inc;
|
||||
source include/have_innodb.inc;
|
||||
|
||||
--echo **** On Slave ****
|
||||
connection slave;
|
||||
source include/have_innodb.inc;
|
||||
STOP SLAVE;
|
||||
|
||||
--echo **** On Master ****
|
||||
@ -69,3 +71,240 @@ query_vertical SHOW SLAVE STATUS;
|
||||
connection master;
|
||||
DROP TABLE t1, t2;
|
||||
sync_slave_with_master;
|
||||
|
||||
#
|
||||
# More tests for BUG#28618
|
||||
#
|
||||
# Case 1.
|
||||
# ROW binlog format and non-transactional tables.
|
||||
# Create the group of events via triggers and try to skip
|
||||
# some items of that group.
|
||||
#
|
||||
|
||||
connection master;
|
||||
SET SESSION BINLOG_FORMAT=ROW;
|
||||
SET AUTOCOMMIT=0;
|
||||
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(20)) ENGINE=myisam;
|
||||
CREATE TABLE t2 (a INT, b VARCHAR(20)) ENGINE=myisam;
|
||||
CREATE TABLE t3 (a INT, b VARCHAR(20)) ENGINE=myisam;
|
||||
|
||||
INSERT INTO t1 VALUES (1,'master/slave');
|
||||
INSERT INTO t2 VALUES (1,'master/slave');
|
||||
INSERT INTO t3 VALUES (1,'master/slave');
|
||||
|
||||
DELIMITER |;
|
||||
|
||||
CREATE TRIGGER tr1 AFTER UPDATE on t1 FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO t2 VALUES (NEW.a,NEW.b);
|
||||
DELETE FROM t2 WHERE a < NEW.a;
|
||||
END|
|
||||
|
||||
CREATE TRIGGER tr2 AFTER INSERT on t2 FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE t3 SET a =2, b = 'master only';
|
||||
END|
|
||||
|
||||
DELIMITER ;|
|
||||
|
||||
--echo **** On Slave ****
|
||||
sync_slave_with_master;
|
||||
STOP SLAVE;
|
||||
source include/wait_for_slave_to_stop.inc;
|
||||
|
||||
--echo **** On Master ****
|
||||
connection master;
|
||||
UPDATE t1 SET a = 2, b = 'master only' WHERE a = 1;
|
||||
DROP TRIGGER tr1;
|
||||
DROP TRIGGER tr2;
|
||||
INSERT INTO t1 VALUES (3,'master/slave');
|
||||
INSERT INTO t2 VALUES (3,'master/slave');
|
||||
INSERT INTO t3 VALUES (3,'master/slave');
|
||||
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
SELECT * FROM t3 ORDER BY a;
|
||||
|
||||
save_master_pos;
|
||||
|
||||
--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;
|
||||
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
SELECT * FROM t3 ORDER BY a;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t1, t2, t3;
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo **** Case 2: Row binlog format and transactional tables ****
|
||||
|
||||
# Create the transaction and try to skip some
|
||||
# queries from one.
|
||||
|
||||
--echo *** On Master ***
|
||||
connection master;
|
||||
CREATE TABLE t4 (a INT, b VARCHAR(20)) ENGINE=innodb;
|
||||
CREATE TABLE t5 (a INT, b VARCHAR(20)) ENGINE=innodb;
|
||||
CREATE TABLE t6 (a INT, b VARCHAR(20)) ENGINE=innodb;
|
||||
|
||||
--echo **** On Slave ****
|
||||
sync_slave_with_master;
|
||||
STOP SLAVE;
|
||||
source include/wait_for_slave_to_stop.inc;
|
||||
|
||||
--echo *** On Master ***
|
||||
connection master;
|
||||
BEGIN;
|
||||
INSERT INTO t4 VALUES (2, 'master only');
|
||||
INSERT INTO t5 VALUES (2, 'master only');
|
||||
INSERT INTO t6 VALUES (2, 'master only');
|
||||
COMMIT;
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO t4 VALUES (3, 'master/slave');
|
||||
INSERT INTO t5 VALUES (3, 'master/slave');
|
||||
INSERT INTO t6 VALUES (3, 'master/slave');
|
||||
COMMIT;
|
||||
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
|
||||
save_master_pos;
|
||||
|
||||
--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;
|
||||
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
|
||||
# Test skipping two groups
|
||||
|
||||
--echo **** On Slave ****
|
||||
connection slave;
|
||||
STOP SLAVE;
|
||||
source include/wait_for_slave_to_stop.inc;
|
||||
|
||||
--echo *** On Master ***
|
||||
connection master;
|
||||
BEGIN;
|
||||
INSERT INTO t4 VALUES (6, 'master only');
|
||||
INSERT INTO t5 VALUES (6, 'master only');
|
||||
INSERT INTO t6 VALUES (6, 'master only');
|
||||
COMMIT;
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO t4 VALUES (7, 'master only');
|
||||
INSERT INTO t5 VALUES (7, 'master only');
|
||||
INSERT INTO t6 VALUES (7, 'master only');
|
||||
COMMIT;
|
||||
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
|
||||
save_master_pos;
|
||||
|
||||
--echo *** On Slave ***
|
||||
connection slave;
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=10;
|
||||
START SLAVE;
|
||||
source include/wait_for_slave_to_start.inc;
|
||||
sync_with_master;
|
||||
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
|
||||
#
|
||||
# And the same, but with autocommit = 0
|
||||
#
|
||||
connection slave;
|
||||
STOP SLAVE;
|
||||
source include/wait_for_slave_to_stop.inc;
|
||||
|
||||
connection master;
|
||||
SET AUTOCOMMIT=0;
|
||||
|
||||
INSERT INTO t4 VALUES (4, 'master only');
|
||||
INSERT INTO t5 VALUES (4, 'master only');
|
||||
INSERT INTO t6 VALUES (4, 'master only');
|
||||
COMMIT;
|
||||
|
||||
INSERT INTO t4 VALUES (5, 'master/slave');
|
||||
INSERT INTO t5 VALUES (5, 'master/slave');
|
||||
INSERT INTO t6 VALUES (5, 'master/slave');
|
||||
COMMIT;
|
||||
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
|
||||
save_master_pos;
|
||||
|
||||
--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;
|
||||
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
SELECT * FROM t5 ORDER BY a;
|
||||
SELECT * FROM t6 ORDER BY a;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t4, t5, t6;
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo **** Case 3: Statement logging format and LOAD DATA with non-transactional table ****
|
||||
|
||||
# LOAD DATA creates two events in binary log for statement binlog format.
|
||||
# Try to skip the first.
|
||||
|
||||
--echo *** On Master ***
|
||||
connection master;
|
||||
CREATE TABLE t10 (a INT, b VARCHAR(20)) ENGINE=myisam;
|
||||
|
||||
--echo *** On Slave ***
|
||||
sync_slave_with_master;
|
||||
STOP SLAVE;
|
||||
source include/wait_for_slave_to_stop.inc;
|
||||
|
||||
--echo *** On Master ***
|
||||
connection master;
|
||||
SET SESSION BINLOG_FORMAT=STATEMENT;
|
||||
exec cp ./suite/rpl/data/rpl_bug28618.dat $MYSQLTEST_VARDIR/tmp/;
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/rpl_bug28618.dat' INTO TABLE t10 FIELDS TERMINATED BY '|';
|
||||
remove_file $MYSQLTEST_VARDIR/tmp/rpl_bug28618.dat;
|
||||
|
||||
SELECT * FROM t10 ORDER BY a;
|
||||
|
||||
save_master_pos;
|
||||
|
||||
--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;
|
||||
|
||||
SELECT * FROM t10 ORDER BY a;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t10;
|
||||
sync_slave_with_master;
|
||||
|
||||
|
@ -707,7 +707,7 @@ Last_IO_Errno #
|
||||
Last_IO_Error #
|
||||
Last_SQL_Errno 1060
|
||||
Last_SQL_Error Error 'Duplicate column name 'c6'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c6 INT AFTER c5'
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
*** Try to insert in master ****
|
||||
INSERT INTO t15 () VALUES(5,2.00,'Replication Testing',@b1,'Buda',2);
|
||||
|
@ -570,7 +570,8 @@ Log_event::do_shall_skip(Relay_log_info *rli)
|
||||
(ulong) server_id, (ulong) ::server_id,
|
||||
rli->replicate_same_server_id,
|
||||
rli->slave_skip_counter));
|
||||
if (server_id == ::server_id && !rli->replicate_same_server_id)
|
||||
if (server_id == ::server_id && !rli->replicate_same_server_id ||
|
||||
rli->slave_skip_counter == 1 && rli->is_in_group())
|
||||
return EVENT_SKIP_IGNORE;
|
||||
else if (rli->slave_skip_counter > 0)
|
||||
return EVENT_SKIP_COUNT;
|
||||
@ -1227,6 +1228,16 @@ void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
|
||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
||||
inline Log_event::enum_skip_reason
|
||||
Log_event::continue_group(Relay_log_info *rli)
|
||||
{
|
||||
if (rli->slave_skip_counter == 1)
|
||||
return Log_event::EVENT_SKIP_IGNORE;
|
||||
return Log_event::do_shall_skip(rli);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
Query_log_event methods
|
||||
**************************************************************************/
|
||||
@ -2235,6 +2246,30 @@ int Query_log_event::do_update_pos(Relay_log_info *rli)
|
||||
}
|
||||
|
||||
|
||||
Log_event::enum_skip_reason
|
||||
Query_log_event::do_shall_skip(Relay_log_info *rli)
|
||||
{
|
||||
DBUG_ENTER("Query_log_event::do_shall_skip");
|
||||
DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
|
||||
DBUG_ASSERT(query && q_len > 0);
|
||||
|
||||
if (rli->slave_skip_counter > 0)
|
||||
{
|
||||
if (strcmp("BEGIN", query) == 0)
|
||||
{
|
||||
thd->options|= OPTION_BEGIN;
|
||||
DBUG_RETURN(Log_event::continue_group(rli));
|
||||
}
|
||||
|
||||
if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
|
||||
{
|
||||
thd->options&= ~OPTION_BEGIN;
|
||||
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(Log_event::do_shall_skip(rli));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -3871,10 +3906,7 @@ Intvar_log_event::do_shall_skip(Relay_log_info *rli)
|
||||
that we do not change the value of the slave skip counter since it
|
||||
will be decreased by the following insert event.
|
||||
*/
|
||||
if (rli->slave_skip_counter == 1)
|
||||
return Log_event::EVENT_SKIP_IGNORE;
|
||||
else
|
||||
return Log_event::do_shall_skip(rli);
|
||||
return continue_group(rli);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -3970,10 +4002,7 @@ Rand_log_event::do_shall_skip(Relay_log_info *rli)
|
||||
that we do not change the value of the slave skip counter since it
|
||||
will be decreased by the following insert event.
|
||||
*/
|
||||
if (rli->slave_skip_counter == 1)
|
||||
return Log_event::EVENT_SKIP_IGNORE;
|
||||
else
|
||||
return Log_event::do_shall_skip(rli);
|
||||
return continue_group(rli);
|
||||
}
|
||||
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
@ -4049,6 +4078,17 @@ int Xid_log_event::do_apply_event(Relay_log_info const *rli)
|
||||
"COMMIT /* implicit, from Xid_log_event */");
|
||||
return end_trans(thd, COMMIT);
|
||||
}
|
||||
|
||||
Log_event::enum_skip_reason
|
||||
Xid_log_event::do_shall_skip(Relay_log_info *rli)
|
||||
{
|
||||
DBUG_ENTER("Xid_log_event::do_shall_skip");
|
||||
if (rli->slave_skip_counter > 0) {
|
||||
thd->options&= ~OPTION_BEGIN;
|
||||
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
|
||||
}
|
||||
DBUG_RETURN(Log_event::do_shall_skip(rli));
|
||||
}
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
|
||||
@ -4427,10 +4467,7 @@ User_var_log_event::do_shall_skip(Relay_log_info *rli)
|
||||
that we do not change the value of the slave skip counter since it
|
||||
will be decreased by the following insert event.
|
||||
*/
|
||||
if (rli->slave_skip_counter == 1)
|
||||
return Log_event::EVENT_SKIP_IGNORE;
|
||||
else
|
||||
return Log_event::do_shall_skip(rli);
|
||||
return continue_group(rli);
|
||||
}
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
@ -5366,6 +5403,19 @@ int Begin_load_query_log_event::get_create_or_append() const
|
||||
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
|
||||
|
||||
|
||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
||||
Log_event::enum_skip_reason
|
||||
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
|
||||
{
|
||||
/*
|
||||
If the slave skip counter is 1, then we should not start executing
|
||||
on the next event.
|
||||
*/
|
||||
return continue_group(rli);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Execute_load_query_log_event methods
|
||||
**************************************************************************/
|
||||
@ -6870,10 +6920,7 @@ Table_map_log_event::do_shall_skip(Relay_log_info *rli)
|
||||
If the slave skip counter is 1, then we should not start executing
|
||||
on the next event.
|
||||
*/
|
||||
if (rli->slave_skip_counter == 1)
|
||||
return Log_event::EVENT_SKIP_IGNORE;
|
||||
else
|
||||
return Log_event::do_shall_skip(rli);
|
||||
return continue_group(rli);
|
||||
}
|
||||
|
||||
int Table_map_log_event::do_update_pos(Relay_log_info *rli)
|
||||
|
@ -870,6 +870,25 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
Helper function to ignore an event w.r.t. the slave skip counter.
|
||||
|
||||
This function can be used inside do_shall_skip() for functions
|
||||
that cannot end a group. If the slave skip counter is 1 when
|
||||
seeing such an event, the event shall be ignored, the counter
|
||||
left intact, and processing continue with the next event.
|
||||
|
||||
A typical usage is:
|
||||
@code
|
||||
enum_skip_reason do_shall_skip(Relay_log_info *rli) {
|
||||
return continue_group(rli);
|
||||
}
|
||||
@endcode
|
||||
|
||||
@return Skip reason
|
||||
*/
|
||||
enum_skip_reason continue_group(Relay_log_info *rli);
|
||||
|
||||
/**
|
||||
Primitive to apply an event to the database.
|
||||
|
||||
@ -1086,6 +1105,7 @@ public:
|
||||
|
||||
public: /* !!! Public in this patch to allow old usage */
|
||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
||||
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
|
||||
virtual int do_apply_event(Relay_log_info const *rli);
|
||||
virtual int do_update_pos(Relay_log_info *rli);
|
||||
|
||||
@ -1559,6 +1579,7 @@ class Xid_log_event: public Log_event
|
||||
private:
|
||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
||||
virtual int do_apply_event(Relay_log_info const *rli);
|
||||
enum_skip_reason do_shall_skip(Relay_log_info *rli);
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1937,6 +1958,10 @@ public:
|
||||
*description_event);
|
||||
~Begin_load_query_log_event() {}
|
||||
Log_event_type get_type_code() { return BEGIN_LOAD_QUERY_EVENT; }
|
||||
private:
|
||||
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
|
||||
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -365,6 +365,18 @@ public:
|
||||
m_flags |= (1UL << flag);
|
||||
}
|
||||
|
||||
/**
|
||||
Get the value of a replication state flag.
|
||||
|
||||
@param flag Flag to get value of
|
||||
|
||||
@return @c true if the flag was set, @c false otherwise.
|
||||
*/
|
||||
bool get_flag(enum_state_flag flag)
|
||||
{
|
||||
return m_flags & (1UL << flag);
|
||||
}
|
||||
|
||||
/**
|
||||
Clear the value of a replication state flag.
|
||||
|
||||
|
@ -1853,10 +1853,13 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
|
||||
// EVENT_SKIP_NOT,
|
||||
"not skipped",
|
||||
// EVENT_SKIP_IGNORE,
|
||||
"skipped because event originated from this server",
|
||||
"skipped because event should be ignored",
|
||||
// EVENT_SKIP_COUNT
|
||||
"skipped because event skip counter was non-zero"
|
||||
};
|
||||
DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
|
||||
thd->options & OPTION_BEGIN ? 1 : 0,
|
||||
rli->get_flag(Relay_log_info::IN_STMT)));
|
||||
DBUG_PRINT("skip_event", ("%s event was %s",
|
||||
ev->get_type_str(), explain[reason]));
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user