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