Browse Source
MWL#234: Support for marking binlog events to not be replicated, and for telling slaves not to replicate events with such mark
pull/374/head
MWL#234: Support for marking binlog events to not be replicated, and for telling slaves not to replicate events with such mark
pull/374/head
13 changed files with 677 additions and 39 deletions
-
38client/mysqlbinlog.cc
-
2configure.in
-
162mysql-test/suite/rpl/r/rpl_do_not_replicate.result
-
245mysql-test/suite/rpl/t/rpl_do_not_replicate.test
-
18sql/log_event.cc
-
26sql/log_event.h
-
2sql/mysql_priv.h
-
10sql/mysqld.cc
-
56sql/set_var.cc
-
19sql/set_var.h
-
52sql/slave.cc
-
9sql/sql_binlog.cc
-
77sql/sql_repl.cc
@ -0,0 +1,162 @@ |
|||||
|
include/master-slave.inc |
||||
|
[connection master] |
||||
|
CREATE USER 'nonsuperuser'@'127.0.0.1'; |
||||
|
GRANT ALTER,CREATE,DELETE,DROP,EVENT,INSERT,PROCESS,REPLICATION SLAVE, |
||||
|
SELECT,UPDATE ON *.* TO 'nonsuperuser'@'127.0.0.1'; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
ERROR 42000: Access denied; you need the SUPER privilege for this operation |
||||
|
DROP USER'nonsuperuser'@'127.0.0.1'; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
START SLAVE; |
||||
|
SET do_not_replicate=0; |
||||
|
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=myisam; |
||||
|
CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=innodb; |
||||
|
INSERT INTO t1(a) VALUES (1); |
||||
|
INSERT INTO t2(a) VALUES (1); |
||||
|
SET do_not_replicate=1; |
||||
|
CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; |
||||
|
INSERT INTO t1(a) VALUES (2); |
||||
|
INSERT INTO t2(a) VALUES (2); |
||||
|
FLUSH NO_WRITE_TO_BINLOG LOGS; |
||||
|
SHOW TABLES; |
||||
|
Tables_in_test |
||||
|
t1 |
||||
|
t2 |
||||
|
SELECT * FROM t1; |
||||
|
a b |
||||
|
1 NULL |
||||
|
SELECT * FROM t2; |
||||
|
a b |
||||
|
1 NULL |
||||
|
DROP TABLE t3; |
||||
|
FLUSH NO_WRITE_TO_BINLOG LOGS; |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=0; |
||||
|
START SLAVE; |
||||
|
CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; |
||||
|
INSERT INTO t3(a) VALUES(2); |
||||
|
SELECT * FROM t3; |
||||
|
a b |
||||
|
2 NULL |
||||
|
DROP TABLE t3; |
||||
|
TRUNCATE t1; |
||||
|
RESET MASTER; |
||||
|
SET do_not_replicate=0; |
||||
|
INSERT INTO t1 VALUES (1,0); |
||||
|
SET do_not_replicate=1; |
||||
|
INSERT INTO t1 VALUES (2,0); |
||||
|
SET do_not_replicate=0; |
||||
|
INSERT INTO t1 VALUES (3,0); |
||||
|
SELECT * FROM t1 ORDER by a; |
||||
|
a b |
||||
|
1 0 |
||||
|
2 0 |
||||
|
3 0 |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
TRUNCATE t1; |
||||
|
SELECT * FROM t1 ORDER by a; |
||||
|
a b |
||||
|
1 0 |
||||
|
2 0 |
||||
|
3 0 |
||||
|
START SLAVE; |
||||
|
SELECT * FROM t1 ORDER by a; |
||||
|
a b |
||||
|
1 0 |
||||
|
3 0 |
||||
|
TRUNCATE t1; |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL sql_slave_skip_counter=2; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
START SLAVE; |
||||
|
SET @old_binlog_format= @@binlog_format; |
||||
|
SET binlog_format= statement; |
||||
|
SET do_not_replicate=0; |
||||
|
INSERT INTO t1 VALUES (1,5); |
||||
|
SET do_not_replicate=1; |
||||
|
INSERT INTO t1 VALUES (2,5); |
||||
|
SET do_not_replicate=0; |
||||
|
INSERT INTO t1 VALUES (3,5); |
||||
|
INSERT INTO t1 VALUES (4,5); |
||||
|
SET binlog_format= @old_binlog_format; |
||||
|
SELECT * FROM t1; |
||||
|
a b |
||||
|
4 5 |
||||
|
TRUNCATE t1; |
||||
|
BINLOG '66I6Tg8BAAAAZgAAAGoAAAABAAQANS40LjAtTWFyaWFEQi12YWxncmluZC1tYXgtZGVidWctbG9n |
||||
|
AAAAAAAAAAAAAAAAAADrojpOEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC'; |
||||
|
BINLOG 'HaM6ThMBAAAAKgAAANgAAAAAgA8AAAAAAAEABHRlc3QAAnQxAAIDAwAC |
||||
|
HaM6ThcBAAAAJgAAAP4AAAAAgA8AAAAAAAEAAv/8AQAAAAgAAAA='; |
||||
|
BINLOG 'JqM6ThMBAAAAKgAAALEBAAAAAA8AAAAAAAEABHRlc3QAAnQxAAIDAwAC |
||||
|
JqM6ThcBAAAAJgAAANcBAAAAAA8AAAAAAAEAAv/8AgAAAAgAAAA='; |
||||
|
SELECT * FROM t1 ORDER BY a; |
||||
|
a b |
||||
|
1 8 |
||||
|
2 8 |
||||
|
SELECT * FROM t1 ORDER by a; |
||||
|
a b |
||||
|
2 8 |
||||
|
SET do_not_replicate=0; |
||||
|
BEGIN; |
||||
|
SET do_not_replicate=0; |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
SET do_not_replicate=1; |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
ROLLBACK; |
||||
|
SET do_not_replicate=1; |
||||
|
BEGIN; |
||||
|
SET do_not_replicate=0; |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
SET do_not_replicate=1; |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
COMMIT; |
||||
|
SET autocommit=0; |
||||
|
INSERT INTO t2(a) VALUES(100); |
||||
|
SET do_not_replicate=1; |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
ROLLBACK; |
||||
|
SET autocommit=1; |
||||
|
SET do_not_replicate=1; |
||||
|
CREATE FUNCTION foo (x INT) RETURNS INT BEGIN SET SESSION do_not_replicate=x; RETURN x; END| |
||||
|
CREATE PROCEDURE bar(x INT) BEGIN SET SESSION do_not_replicate=x; END| |
||||
|
CREATE FUNCTION baz (x INT) RETURNS INT BEGIN CALL bar(x); RETURN x; END| |
||||
|
SELECT foo(0); |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
SELECT baz(0); |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
SET @a= foo(1); |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
SET @a= baz(1); |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
UPDATE t2 SET b=foo(0); |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
UPDATE t2 SET b=baz(0); |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
INSERT INTO t1 VALUES (101, foo(1)); |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
INSERT INTO t1 VALUES (101, baz(0)); |
||||
|
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction |
||||
|
SELECT @@do_not_replicate; |
||||
|
@@do_not_replicate |
||||
|
1 |
||||
|
CALL bar(0); |
||||
|
SELECT @@do_not_replicate; |
||||
|
@@do_not_replicate |
||||
|
0 |
||||
|
CALL bar(1); |
||||
|
SELECT @@do_not_replicate; |
||||
|
@@do_not_replicate |
||||
|
1 |
||||
|
DROP FUNCTION foo; |
||||
|
DROP PROCEDURE bar; |
||||
|
DROP FUNCTION baz; |
||||
|
SET do_not_replicate=0; |
||||
|
DROP TABLE t1,t2; |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=0; |
||||
|
START SLAVE; |
||||
|
include/rpl_end.inc |
||||
@ -0,0 +1,245 @@ |
|||||
|
--source include/master-slave.inc |
||||
|
--source include/have_innodb.inc |
||||
|
|
||||
|
connection slave; |
||||
|
# Test that SUPER is required to change @@replicate_ignore_do_not_replicate. |
||||
|
CREATE USER 'nonsuperuser'@'127.0.0.1'; |
||||
|
GRANT ALTER,CREATE,DELETE,DROP,EVENT,INSERT,PROCESS,REPLICATION SLAVE, |
||||
|
SELECT,UPDATE ON *.* TO 'nonsuperuser'@'127.0.0.1'; |
||||
|
connect(nonpriv, 127.0.0.1, nonsuperuser,, test, $SLAVE_MYPORT,); |
||||
|
connection nonpriv; |
||||
|
--error ER_SPECIFIC_ACCESS_DENIED_ERROR |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
disconnect nonpriv; |
||||
|
connection slave; |
||||
|
DROP USER'nonsuperuser'@'127.0.0.1'; |
||||
|
|
||||
|
--error ER_SLAVE_MUST_STOP |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
START SLAVE; |
||||
|
|
||||
|
connection master; |
||||
|
SET do_not_replicate=0; |
||||
|
|
||||
|
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=myisam; |
||||
|
CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=innodb; |
||||
|
INSERT INTO t1(a) VALUES (1); |
||||
|
INSERT INTO t2(a) VALUES (1); |
||||
|
|
||||
|
SET do_not_replicate=1; |
||||
|
|
||||
|
CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; |
||||
|
INSERT INTO t1(a) VALUES (2); |
||||
|
INSERT INTO t2(a) VALUES (2); |
||||
|
|
||||
|
# Inject a rotate event in the binlog stream sent to slave (otherwise we will |
||||
|
# fail sync_slave_with_master as the last event on the master is not present |
||||
|
# on the slave). |
||||
|
FLUSH NO_WRITE_TO_BINLOG LOGS; |
||||
|
|
||||
|
sync_slave_with_master; |
||||
|
connection slave; |
||||
|
SHOW TABLES; |
||||
|
SELECT * FROM t1; |
||||
|
SELECT * FROM t2; |
||||
|
|
||||
|
connection master; |
||||
|
DROP TABLE t3; |
||||
|
|
||||
|
FLUSH NO_WRITE_TO_BINLOG LOGS; |
||||
|
sync_slave_with_master; |
||||
|
connection slave; |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=0; |
||||
|
START SLAVE; |
||||
|
|
||||
|
connection master; |
||||
|
CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; |
||||
|
INSERT INTO t3(a) VALUES(2); |
||||
|
sync_slave_with_master; |
||||
|
connection slave; |
||||
|
SELECT * FROM t3; |
||||
|
connection master; |
||||
|
DROP TABLE t3; |
||||
|
|
||||
|
# |
||||
|
# Test that the slave will preserve the @@do_not_replicate flag in its |
||||
|
# own binlog. |
||||
|
# |
||||
|
|
||||
|
TRUNCATE t1; |
||||
|
sync_slave_with_master; |
||||
|
connection slave; |
||||
|
RESET MASTER; |
||||
|
|
||||
|
connection master; |
||||
|
SET do_not_replicate=0; |
||||
|
INSERT INTO t1 VALUES (1,0); |
||||
|
SET do_not_replicate=1; |
||||
|
INSERT INTO t1 VALUES (2,0); |
||||
|
SET do_not_replicate=0; |
||||
|
INSERT INTO t1 VALUES (3,0); |
||||
|
|
||||
|
sync_slave_with_master; |
||||
|
connection slave; |
||||
|
# Since slave has @@replicate_ignore_do_not_replicate=0, it should have |
||||
|
# applied all events. |
||||
|
SELECT * FROM t1 ORDER by a; |
||||
|
|
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
let $SLAVE_DATADIR= `select @@datadir`; |
||||
|
|
||||
|
connection master; |
||||
|
TRUNCATE t1; |
||||
|
|
||||
|
# Now apply the slave binlog to the master, to check that both the slave |
||||
|
# and mysqlbinlog will preserve the @@do_not_replicate flag. |
||||
|
--exec $MYSQL_BINLOG $SLAVE_DATADIR/slave-bin.000001 > $MYSQLTEST_VARDIR/tmp/rpl_do_not_replicate.binlog |
||||
|
--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/rpl_do_not_replicate.binlog |
||||
|
|
||||
|
# The master should have all three events. |
||||
|
SELECT * FROM t1 ORDER by a; |
||||
|
|
||||
|
# The slave should be missing event 2, which is marked with the |
||||
|
# @@do_not_replicate flag. |
||||
|
|
||||
|
connection slave; |
||||
|
START SLAVE; |
||||
|
|
||||
|
connection master; |
||||
|
sync_slave_with_master; |
||||
|
|
||||
|
connection slave; |
||||
|
SELECT * FROM t1 ORDER by a; |
||||
|
|
||||
|
# |
||||
|
# Test that @@sql_slave_skip_counter does not count skipped @@do_not_replicate |
||||
|
# events. |
||||
|
# |
||||
|
|
||||
|
connection master; |
||||
|
TRUNCATE t1; |
||||
|
|
||||
|
sync_slave_with_master; |
||||
|
connection slave; |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL sql_slave_skip_counter=2; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=1; |
||||
|
START SLAVE; |
||||
|
|
||||
|
connection master; |
||||
|
# Need to fix @@binlog_format to get consistent event count. |
||||
|
SET @old_binlog_format= @@binlog_format; |
||||
|
SET binlog_format= statement; |
||||
|
SET do_not_replicate=0; |
||||
|
INSERT INTO t1 VALUES (1,5); |
||||
|
SET do_not_replicate=1; |
||||
|
INSERT INTO t1 VALUES (2,5); |
||||
|
SET do_not_replicate=0; |
||||
|
INSERT INTO t1 VALUES (3,5); |
||||
|
INSERT INTO t1 VALUES (4,5); |
||||
|
SET binlog_format= @old_binlog_format; |
||||
|
|
||||
|
sync_slave_with_master; |
||||
|
connection slave; |
||||
|
|
||||
|
# The slave should have skipped the first three inserts (number 1 and 3 due |
||||
|
# to @@sql_slave_skip_counter=2, number 2 due to |
||||
|
# @@replicate_ignore_do_not_replicate=1). So only number 4 should be left. |
||||
|
SELECT * FROM t1; |
||||
|
|
||||
|
|
||||
|
# |
||||
|
# Check that BINLOG statement preserves the @@do_not_replicate flag. |
||||
|
# |
||||
|
connection master; |
||||
|
TRUNCATE t1; |
||||
|
|
||||
|
# Format description log event. |
||||
|
BINLOG '66I6Tg8BAAAAZgAAAGoAAAABAAQANS40LjAtTWFyaWFEQi12YWxncmluZC1tYXgtZGVidWctbG9n |
||||
|
AAAAAAAAAAAAAAAAAADrojpOEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC'; |
||||
|
# INSERT INTO t1 VALUES (1,8) # with @@do_not_replicate=1 |
||||
|
BINLOG 'HaM6ThMBAAAAKgAAANgAAAAAgA8AAAAAAAEABHRlc3QAAnQxAAIDAwAC |
||||
|
HaM6ThcBAAAAJgAAAP4AAAAAgA8AAAAAAAEAAv/8AQAAAAgAAAA='; |
||||
|
# INSERT INTO t1 VALUES (2,8) # with @@do_not_replicate=0 |
||||
|
BINLOG 'JqM6ThMBAAAAKgAAALEBAAAAAA8AAAAAAAEABHRlc3QAAnQxAAIDAwAC |
||||
|
JqM6ThcBAAAAJgAAANcBAAAAAA8AAAAAAAEAAv/8AgAAAAgAAAA='; |
||||
|
|
||||
|
SELECT * FROM t1 ORDER BY a; |
||||
|
sync_slave_with_master; |
||||
|
connection slave; |
||||
|
# Slave should have only the second insert, the first should be ignored due to |
||||
|
# the @@do_not_replicate flag. |
||||
|
SELECT * FROM t1 ORDER by a; |
||||
|
|
||||
|
|
||||
|
# Test that it is not possible to d change @@do_not_replicate inside a |
||||
|
# transaction or statement, thereby replicating only parts of statements |
||||
|
# or transactions. |
||||
|
connection master; |
||||
|
SET do_not_replicate=0; |
||||
|
|
||||
|
BEGIN; |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SET do_not_replicate=0; |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SET do_not_replicate=1; |
||||
|
ROLLBACK; |
||||
|
SET do_not_replicate=1; |
||||
|
BEGIN; |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SET do_not_replicate=0; |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SET do_not_replicate=1; |
||||
|
COMMIT; |
||||
|
SET autocommit=0; |
||||
|
INSERT INTO t2(a) VALUES(100); |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SET do_not_replicate=1; |
||||
|
ROLLBACK; |
||||
|
SET autocommit=1; |
||||
|
|
||||
|
SET do_not_replicate=1; |
||||
|
--delimiter | |
||||
|
CREATE FUNCTION foo (x INT) RETURNS INT BEGIN SET SESSION do_not_replicate=x; RETURN x; END| |
||||
|
CREATE PROCEDURE bar(x INT) BEGIN SET SESSION do_not_replicate=x; END| |
||||
|
CREATE FUNCTION baz (x INT) RETURNS INT BEGIN CALL bar(x); RETURN x; END| |
||||
|
--delimiter ; |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SELECT foo(0); |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SELECT baz(0); |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SET @a= foo(1); |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
SET @a= baz(1); |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
UPDATE t2 SET b=foo(0); |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
UPDATE t2 SET b=baz(0); |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
INSERT INTO t1 VALUES (101, foo(1)); |
||||
|
--error ER_LOCK_OR_ACTIVE_TRANSACTION |
||||
|
INSERT INTO t1 VALUES (101, baz(0)); |
||||
|
SELECT @@do_not_replicate; |
||||
|
CALL bar(0); |
||||
|
SELECT @@do_not_replicate; |
||||
|
CALL bar(1); |
||||
|
SELECT @@do_not_replicate; |
||||
|
DROP FUNCTION foo; |
||||
|
DROP PROCEDURE bar; |
||||
|
DROP FUNCTION baz; |
||||
|
|
||||
|
# Clean up. |
||||
|
connection master; |
||||
|
SET do_not_replicate=0; |
||||
|
DROP TABLE t1,t2; |
||||
|
connection slave; |
||||
|
STOP SLAVE; |
||||
|
SET GLOBAL replicate_ignore_do_not_replicate=0; |
||||
|
START SLAVE; |
||||
|
|
||||
|
--source include/rpl_end.inc |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue