Index: /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/t/rpl_circular_event_detect.cnf =================================================================== --- /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/t/rpl_circular_event_detect.cnf (revision 0) +++ /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/t/rpl_circular_event_detect.cnf (revision 1861) @@ -0,0 +1,10 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +innodb + +[mysqld.2] +log-slave-updates +innodb + Index: /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/t/rpl_circular_event_detect.test =================================================================== --- /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/t/rpl_circular_event_detect.test (revision 0) +++ /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/t/rpl_circular_event_detect.test (revision 1861) @@ -0,0 +1,86 @@ +# ==== Purpose ==== +# +# Confirm abnormal event with another server_id would be passed +# among the circular replacted hosts, and it should be detected +# with warning information. +# +# +# ==== Related bugs and worklogs ==== +# + +# 1. setup environment: +# server1(server_id=1) <---(dual master)--> server2(server_id=2) +# 2. create table t on server1, and it should be replicated to server2 +# 3. stop slave on server1 +# 4. insert one record on server1 +# 5. change server_id from 1 to 3 on server1 +# 6. start slave on server1 +# 7. expected record more than 1 on server1 (also warning of dual master for event) + + +--source include/have_innodb.inc +# Use wait_for_slave_to_(start|stop) for current connections +let $keep_connection= 1; + +# Set up circular ring and new names for servers +--echo [set up circular replication on two servers] +--let $rpl_topology= 1->2->1 +--source include/rpl_init.inc +--echo + +# Preparing data on server1. +--echo [preparing data on server1] +--connection server_1 + +# make sure log_slave_updates is on +#SET session log_slave_updates=on; + +#CREATE TABLE IF NOT EXISTS t (a INT NOT NULL AUTO_INCREMENT, b VARCHAR(100), PRIMARY KEY(a)) ENGINE=InnoDB; +CREATE TABLE IF NOT EXISTS t (a VARCHAR(100)) ENGINE=InnoDB; + +--echo [skip create table events on server1] +#CHANGE MASTER TO master_log_pos=276; + +call mtr.add_suppression("Detect dual master circular topological structure *"); + +--real_sleep 1 +STOP SLAVE; + +--connection server_2 +STOP SLAVE; + +--connection server_1 +INSERT INTO t values('abc'); + +SET GLOBAL SERVER_ID = 3; +START SLAVE; + +--connection server_2 +START SLAVE; + + +#--real_sleep 3 + +--connection server_1 +let $wait_condition= SELECT COUNT(*) > 10 FROM t; +--source include/wait_condition.inc +#select * from t; + +--connection server_2 +#select * from t; + +--echo +--echo *** detect event with circle A->B->A *** +--echo + +--disable_warnings + +# Clean up environment +--echo [clean up] + +--connection server_1 +SET GLOBAL SERVER_ID = 1; +DROP TABLE IF EXISTS t; + +--source include/rpl_reset.inc +--source include/rpl_end.inc Index: /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/r/rpl_circular_event_detect.result =================================================================== --- /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/r/rpl_circular_event_detect.result (revision 0) +++ /PS5518/branches/PS-r1331-rpl-circular/mysql-test/suite/rpl/r/rpl_circular_event_detect.result (revision 1861) @@ -0,0 +1,21 @@ +[set up circular replication on two servers] +include/rpl_init.inc [topology=1->2->1] + +[preparing data on server1] +CREATE TABLE IF NOT EXISTS t (a VARCHAR(100)) ENGINE=InnoDB; +[skip create table events on server1] +call mtr.add_suppression("Detect dual master circular topological structure *"); +STOP SLAVE; +STOP SLAVE; +INSERT INTO t values('abc'); +SET GLOBAL SERVER_ID = 3; +START SLAVE; +START SLAVE; + +*** detect event with circle A->B->A *** + +[clean up] +SET GLOBAL SERVER_ID = 1; +DROP TABLE IF EXISTS t; +include/rpl_reset.inc +include/rpl_end.inc Index: /PS5518/branches/PS-r1331-rpl-circular/sql/repl_failsafe.h =================================================================== --- /PS5518/branches/PS-r1331-rpl-circular/sql/repl_failsafe.h (revision 1824) +++ /PS5518/branches/PS-r1331-rpl-circular/sql/repl_failsafe.h (revision 1861) @@ -37,6 +37,7 @@ int find_recovery_captain(THD* thd, MYSQL* mysql); extern HASH slave_list; +extern bool rpl_circular_warning; bool show_slave_hosts(THD* thd); void init_slave_list(); Index: /PS5518/branches/PS-r1331-rpl-circular/sql/repl_failsafe.cc =================================================================== --- /PS5518/branches/PS-r1331-rpl-circular/sql/repl_failsafe.cc (revision 1824) +++ /PS5518/branches/PS-r1331-rpl-circular/sql/repl_failsafe.cc (revision 1861) @@ -151,6 +151,8 @@ mysql_mutex_lock(&LOCK_slave_list); unregister_slave(thd,0,0); res= my_hash_insert(&slave_list, (uchar*) si); + /*when new slave registerd, rpl circular becomes possible*/ + rpl_circular_warning = true; mysql_mutex_unlock(&LOCK_slave_list); return res; Index: /PS5518/branches/PS-r1331-rpl-circular/sql/slave.cc =================================================================== --- /PS5518/branches/PS-r1331-rpl-circular/sql/slave.cc (revision 1824) +++ /PS5518/branches/PS-r1331-rpl-circular/sql/slave.cc (revision 1861) @@ -75,6 +75,9 @@ my_bool replicate_same_server_id; ulonglong relay_log_space_limit = 0; +/*wheather to show warning message when rpl circular detected*/ +bool rpl_circular_warning = false; + /* When slave thread exits, we need to remember the temporary tables so we can re-use them on slave start. @@ -4060,6 +4063,25 @@ } else { + if (rpl_circular_warning && s_id !=::server_id) + { + /* + if replicated event's server_id is neither the same with current + instance's id, nor id in slave_list, a warning should be given + for dual mastser topological structure. + */ + mysql_mutex_lock(&LOCK_slave_list); + if (!my_hash_search(&slave_list, (uchar*)&s_id, 4) && + my_hash_search(&slave_list, (uchar*)&mi->master_id, 4)) + { + sql_print_warning("Detect dual master circular topological structure: " + " event_sid=%ld, server id=%ld, master(slave) id=%ld ", + s_id, ::server_id, mi->master_id); + rpl_circular_warning = false; + } + mysql_mutex_unlock(&LOCK_slave_list); + } + /* write the event to the relay log */ if (likely(!(rli->relay_log.appendv(buf,event_len,0)))) {