mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 13:02:28 +01:00
f01321fd09
Adding code to keep skipping events while inside a transaction. Execution will start just after the transaction has been skipped. sql/slave.cc: Adding code to set the thd->options flag for the slave SQL thread even when BEGIN, ROLLBACK, COMMIT, and XID events are being skipped. Adding code to not decrease the slave skip counter from 1 to 0 if we are inside a transaction. This will keep the counter at 1, and keep skipping events, until a transaction terminator is read. At that point, the slave skip counter will be decreased to 0, and events will be read and executed instead of read and skipped. mysql-test/r/rpl_slave_skip.result: New BitKeeper file ``mysql-test/r/rpl_slave_skip.result'' mysql-test/t/rpl_slave_skip-slave.opt: New BitKeeper file ``mysql-test/t/rpl_slave_skip-slave.opt'' mysql-test/t/rpl_slave_skip.test: New BitKeeper file ``mysql-test/t/rpl_slave_skip.test''
203 lines
4.8 KiB
Text
203 lines
4.8 KiB
Text
source include/have_innodb.inc;
|
|
source include/master-slave.inc;
|
|
|
|
# This test is for checking that the use of SQL_SLAVE_SKIP_COUNTER
|
|
# behaves as expected, i.e., that it is guaranteed to skip an entire
|
|
# group and not start executing in the middle of a transaction.
|
|
|
|
# We are checking the correct behaviour when using both a
|
|
# transactional and non-transactional table. The non-transactional
|
|
# table comes into play when rolling back a transaction containing a
|
|
# write to this table. In that case, the transaction should still be
|
|
# written to the binary log, and the slave will apply it and then roll
|
|
# 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;
|
|
|
|
--echo ==== Skipping normal transactions ====
|
|
|
|
--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 t1 VALUES (1, 'master');
|
|
INSERT INTO t1 VALUES (2, 'master');
|
|
INSERT INTO t1 VALUES (3, 'master');
|
|
COMMIT;
|
|
|
|
BEGIN;
|
|
INSERT INTO t1 VALUES (4, 'master,slave');
|
|
INSERT INTO t1 VALUES (5, 'master,slave');
|
|
INSERT INTO t1 VALUES (6, 'master,slave');
|
|
COMMIT;
|
|
|
|
save_master_pos;
|
|
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
# 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=2;
|
|
START SLAVE;
|
|
source include/wait_for_slave_to_start.inc;
|
|
sync_with_master;
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
--echo **** On Master ****
|
|
connection master;
|
|
DELETE FROM t1;
|
|
sync_slave_with_master;
|
|
|
|
--echo ==== Skipping two normal transactions ====
|
|
|
|
--echo **** On Slave ****
|
|
connection slave;
|
|
STOP SLAVE;
|
|
source include/wait_for_slave_to_stop.inc;
|
|
|
|
--echo **** On Master ****
|
|
connection master;
|
|
|
|
BEGIN;
|
|
INSERT INTO t1 VALUES (1, 'master');
|
|
INSERT INTO t1 VALUES (2, 'master');
|
|
INSERT INTO t1 VALUES (3, 'master');
|
|
COMMIT;
|
|
|
|
BEGIN;
|
|
INSERT INTO t1 VALUES (4, 'master');
|
|
INSERT INTO t1 VALUES (5, 'master');
|
|
INSERT INTO t1 VALUES (6, 'master');
|
|
COMMIT;
|
|
|
|
BEGIN;
|
|
INSERT INTO t1 VALUES (7, 'master,slave');
|
|
INSERT INTO t1 VALUES (8, 'master,slave');
|
|
INSERT INTO t1 VALUES (9, 'master,slave');
|
|
COMMIT;
|
|
|
|
save_master_pos;
|
|
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
# 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=8;
|
|
START SLAVE;
|
|
source include/wait_for_slave_to_start.inc;
|
|
sync_with_master;
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
--echo **** On Master ****
|
|
connection master;
|
|
DELETE FROM t1;
|
|
sync_slave_with_master;
|
|
|
|
--echo ==== Skipping without autocommit ====
|
|
|
|
# Testing without using autocommit instead. It should still write a
|
|
# BEGIN event, so the behaviour should be the same
|
|
|
|
--echo **** On Slave ****
|
|
connection slave;
|
|
STOP SLAVE;
|
|
source include/wait_for_slave_to_stop.inc;
|
|
|
|
--echo **** On Master ****
|
|
connection master;
|
|
SET AUTOCOMMIT=0;
|
|
|
|
INSERT INTO t1 VALUES (1, 'master');
|
|
INSERT INTO t1 VALUES (2, 'master');
|
|
INSERT INTO t1 VALUES (3, 'master');
|
|
COMMIT;
|
|
|
|
INSERT INTO t1 VALUES (4, 'master,slave');
|
|
INSERT INTO t1 VALUES (5, 'master,slave');
|
|
INSERT INTO t1 VALUES (6, 'master,slave');
|
|
COMMIT;
|
|
|
|
save_master_pos;
|
|
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
# 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=2;
|
|
START SLAVE;
|
|
source include/wait_for_slave_to_start.inc;
|
|
sync_with_master;
|
|
SELECT * FROM t1 ORDER BY a;
|
|
|
|
# Testing with a non-transactional table in the transaction. This will
|
|
# log a ROLLBACK as a transaction terminator, which is a normal Query
|
|
# log event.
|
|
|
|
--echo ==== Rollback of transaction with non-transactional change ====
|
|
|
|
--echo **** On Master ****
|
|
connection master;
|
|
DELETE FROM t1;
|
|
SET AUTOCOMMIT=1;
|
|
|
|
--echo **** On Slave ****
|
|
sync_slave_with_master;
|
|
STOP SLAVE;
|
|
source include/wait_for_slave_to_stop.inc;
|
|
|
|
--echo **** On Master ****
|
|
connection master;
|
|
disable_warnings;
|
|
BEGIN;
|
|
INSERT INTO t1 VALUES (1, '');
|
|
INSERT INTO t2 VALUES (2, 'master');
|
|
INSERT INTO t1 VALUES (3, '');
|
|
ROLLBACK;
|
|
|
|
BEGIN;
|
|
INSERT INTO t1 VALUES (4, '');
|
|
INSERT INTO t2 VALUES (5, 'master,slave');
|
|
INSERT INTO t1 VALUES (6, '');
|
|
ROLLBACK;
|
|
enable_warnings;
|
|
|
|
save_master_pos;
|
|
|
|
SELECT * FROM t1 ORDER BY a;
|
|
SELECT * FROM t2 ORDER BY a;
|
|
|
|
--echo **** On Slave ****
|
|
connection slave;
|
|
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
|
|
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;
|
|
|
|
--echo ==== Cleanup ====
|
|
|
|
--echo **** On Master ****
|
|
connection master;
|
|
DROP TABLE t1, t2;
|
|
sync_slave_with_master;
|