Commit a50ddebb authored by Nirbhay Choubey's avatar Nirbhay Choubey

MDEV-6593 : domain_id based replication filters

Implementation for domain ID based filtering of replication events.
parent 7bf4f9f7
......@@ -64,6 +64,8 @@ if ($tmp)
--echo Master_SSL_Crlpath #
--echo Using_Gtid No
--echo Gtid_IO_Pos #
--echo Replicate_Do_Domain_Ids
--echo Replicate_Ignore_Domain_Ids
}
if (!$tmp) {
# Note: after WL#5177, fields 13-18 shall not be filtered-out.
......
......@@ -84,17 +84,17 @@ MASTER 2.2
# EOF
#
show all slaves status;
Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 313 relay.000002 601 master-bin.000001 Yes Yes 0 0 313 888 None 0 No 0 No 0 0 1 No 0 1073741824 7 0 60.000
MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 313 relay-master@00202@002e2.000002 601 master-bin.000001 Yes Yes 0 0 313 907 None 0 No 0 No 0 0 2 No 0 1073741824 7 0 60.000
Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 313 relay.000002 601 master-bin.000001 Yes Yes 0 0 313 888 None 0 No 0 No 0 0 1 No 0 1073741824 7 0 60.000
MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 313 relay-master@00202@002e2.000002 601 master-bin.000001 Yes Yes 0 0 313 907 None 0 No 0 No 0 0 2 No 0 1073741824 7 0 60.000
include/wait_for_slave_to_start.inc
set default_master_connection = 'MASTER 2.2';
include/wait_for_slave_to_start.inc
set default_master_connection = '';
show all slaves status;
Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 313 relay.000004 536 master-bin.000001 Yes Yes 0 0 313 823 None 0 No 0 No 0 0 1 No 0 1073741824 6 0 60.000
MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 313 relay-master@00202@002e2.000004 536 master-bin.000001 Yes Yes 0 0 313 842 None 0 No 0 No 0 0 2 No 0 1073741824 6 0 60.000
Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 313 relay.000004 536 master-bin.000001 Yes Yes 0 0 313 823 None 0 No 0 No 0 0 1 No 0 1073741824 6 0 60.000
MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 313 relay-master@00202@002e2.000004 536 master-bin.000001 Yes Yes 0 0 313 842 None 0 No 0 No 0 0 2 No 0 1073741824 6 0 60.000
#
# List of files matching '*info*' pattern
# after slave server restart
......
......@@ -10,15 +10,15 @@ create table t1 (i int) engine=MyISAM;
insert into t1 values (1),(2);
stop slave 'master1';
show slave 'master1' status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos
127.0.0.1 root MYPORT_1 60 master-bin.000001 802 mysqld-relay-bin-master1.000002 1090 master-bin.000001 No No 0 0 802 1396 None 0 No NULL No 0 0 1 No
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids
127.0.0.1 root MYPORT_1 60 master-bin.000001 802 mysqld-relay-bin-master1.000002 1090 master-bin.000001 No No 0 0 802 1396 None 0 No NULL No 0 0 1 No
mysqld-relay-bin-master1.000001
mysqld-relay-bin-master1.000002
mysqld-relay-bin-master1.index
reset slave 'master1';
show slave 'master1' status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos
127.0.0.1 root MYPORT_1 60 4 1090 No No 0 0 0 1396 None 0 No NULL No 0 0 1 No
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids
127.0.0.1 root MYPORT_1 60 4 1090 No No 0 0 0 1396 None 0 No NULL No 0 0 1 No
reset slave 'master1' all;
show slave 'master1' status;
ERROR HY000: There is no master connection 'master1'
......
This diff is collapsed.
include/master-slave.inc
[connection master]
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids
show slave '' status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids
show all slaves status;
Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos
#
# Check error handling
#
......
include/master-slave.inc
[connection master]
# On slave
call mtr.add_suppression("Both DO_DOMAIN_IDS & IGNORE_DOMAIN_IDS lists can't be non-empty at the same time");
call mtr.add_suppression("DO_DOMAIN_IDS or IGNORE_DOMAIN_IDS lists can't be non-empty in non-GTID mode.*");
# On master
SET @@session.gtid_domain_id= 1;
SELECT @@session.gtid_domain_id;
@@session.gtid_domain_id
1
CREATE TABLE t1(i INT) ENGINE=INNODB;
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
i
1
# On slave
SELECT * FROM t1;
i
1
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) : 1
IGNORE_DOMAIN_IDS (AFTER) :
# On master
SET @@session.gtid_domain_id= 2;
INSERT INTO t1 VALUES(2);
SET @@session.gtid_domain_id= 1;
INSERT INTO t1 VALUES(3);
SELECT * FROM t1;
i
1
2
3
# On slave
SELECT * FROM t1;
i
1
3
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) : 1
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
# On master
SELECT @@session.gtid_domain_id;
@@session.gtid_domain_id
1
INSERT INTO t1 VALUES(4);
SET @@session.gtid_domain_id= 2;
INSERT INTO t1 VALUES(5);
SELECT * FROM t1;
i
1
2
3
4
5
# On slave
SELECT * FROM t1;
i
1
3
5
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO DO_DOMAIN_IDS=(1), IGNORE_DOMAIN_IDS=(2), MASTER_USE_GTID=slave_pos;
ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
include/stop_slave.inc
Warnings:
Note 1255 Slave already has been stopped
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO DO_DOMAIN_IDS=(4,4,5,1,7,7,7,1,1,2,6,8,1,4,5,5,9,3), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) : 1, 2, 3, 4, 5, 6, 7, 8, 9
IGNORE_DOMAIN_IDS (AFTER) :
# On master
SELECT @@session.gtid_domain_id;
@@session.gtid_domain_id
2
INSERT INTO t1 VALUES(8);
SET @@session.gtid_domain_id= 7;
INSERT INTO t1 VALUES(9);
SET @@session.gtid_domain_id= 10;
INSERT INTO t1 VALUES(10);
INSERT INTO t1 VALUES(11);
START TRANSACTION;
INSERT INTO t1 VALUES(12);
INSERT INTO t1 VALUES(13);
COMMIT;
INSERT INTO t1 VALUES(14);
INSERT INTO t1 VALUES(15);
# On slave
SELECT * FROM t1;
i
1
3
5
8
9
# On slave
# Seconds_Behind_Master should be zero here because the slave is fully caught up and idle.
Seconds_Behind_Master = '0'
# On slave
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) : 1, 2, 3, 4, 5, 6, 7, 8, 9
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
# On master
SET @@session.gtid_domain_id=2;
CREATE TABLE t2(i int) ENGINE=MYISAM;
CREATE TABLE t3(i int) ENGINE=INNODB;
SET @@session.gtid_domain_id=1;
BEGIN;
INSERT INTO t2 VALUES(1);
INSERT INTO t3 VALUES(1);
# On slave
include/stop_slave.inc
include/wait_for_slave_to_stop.inc
# On master
INSERT INTO t2 VALUES(2);
INSERT INTO t3 VALUES(2);
COMMIT;
# On slave
include/start_slave.inc
SELECT * FROM t2;
i
SELECT * FROM t3;
i
# On master
SET @@session.gtid_domain_id=1;
BEGIN;
INSERT INTO t2 VALUES(3);
INSERT INTO t3 VALUES(3);
# On slave
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
# On master
INSERT INTO t2 VALUES(4);
INSERT INTO t3 VALUES(4);
COMMIT;
# On slave
SELECT * FROM t2;
i
4
SELECT * FROM t3;
i
3
4
# On master
SET @@session.gtid_domain_id=1;
BEGIN;
INSERT INTO t2 VALUES(5);
INSERT INTO t3 VALUES(5);
# On slave
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
# On master
INSERT INTO t2 VALUES(6);
INSERT INTO t3 VALUES(6);
COMMIT;
# On slave
SELECT * FROM t2;
i
4
5
SELECT * FROM t3;
i
3
4
# On slave
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(2), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 2
# On master
SET @@session.gtid_domain_id=2;
BEGIN;
INSERT INTO t2 VALUES(7);
INSERT INTO t3 VALUES(7);
COMMIT;
# On slave
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 2
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
# On master
SET @@session.gtid_domain_id=2;
BEGIN;
INSERT INTO t2 VALUES(8);
INSERT INTO t3 VALUES(8);
COMMIT;
SELECT * FROM t2;
i
4
5
8
SELECT * FROM t3;
i
3
4
8
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO DO_DOMAIN_IDS=(1), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log
CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO MASTER_USE_GTID=NO;
ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=NO;
CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=NO;
ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=NO;
ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), DO_DOMAIN_IDS=(), MASTER_USE_GTID=SLAVE_POS;
include/start_slave.inc
# On master
SET @@session.gtid_domain_id=2;
DROP TABLE t1, t2, t3;
# On slave
include/stop_slave.inc
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=();
include/start_slave.inc
include/rpl_end.inc
include/master-slave.inc
[connection master]
# On master
SET @@session.gtid_domain_id= 1;
SELECT @@session.gtid_domain_id;
@@session.gtid_domain_id
1
CREATE TABLE t1(i INT) ENGINE=INNODB;
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
i
1
# On slave
call mtr.add_suppression("Slave I/O: Relay log write failure: could not queue event from master.*");
# Case 0 : Start slave with IGNORE_DOMAIN_IDS=(), then restart
# replication with IGNORE_DOMAIN_IDS=() after IO thread is
# killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_before_commit").
SELECT * FROM t1;
i
1
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
SET @@global.debug_dbug="+d,kill_slave_io_before_commit";
# On master
START TRANSACTION;
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
COMMIT;
SELECT * FROM t1;
i
1
2
3
# On slave
include/wait_for_slave_io_error.inc [errno=1595]
SELECT * FROM t1;
i
1
SET @@global.debug_dbug="-d";
START SLAVE io_thread;
include/wait_for_slave_io_to_start.inc
SELECT * FROM t1;
i
1
2
3
# Case 1 : Start slave with IGNORE_DOMAIN_IDS=(1), then restart
# replication with IGNORE_DOMAIN_IDS=(1) after IO thread is
# killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_before_commit").
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
SET @@global.debug_dbug="+d,kill_slave_io_before_commit";
# On master
START TRANSACTION;
INSERT INTO t1 VALUES(4);
INSERT INTO t1 VALUES(5);
COMMIT;
SELECT * FROM t1;
i
1
2
3
4
5
# On slave
include/wait_for_slave_io_error.inc [errno=1595]
SELECT * FROM t1;
i
1
2
3
SET @@global.debug_dbug="-d";
START SLAVE io_thread;
include/wait_for_slave_io_to_start.inc
SELECT * FROM t1;
i
1
2
3
# Case 2 : Start slave with IGNORE_DOMAIN_IDS=(), then restart
# replication with IGNORE_DOMAIN_IDS=(1) after IO thread is
# killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_before_commit").
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
SET @@global.debug_dbug="+d,kill_slave_io_before_commit";
# On master
START TRANSACTION;
INSERT INTO t1 VALUES(6);
INSERT INTO t1 VALUES(7);
COMMIT;
START TRANSACTION;
INSERT INTO t1 VALUES(8);
INSERT INTO t1 VALUES(9);
COMMIT;
SET @@session.gtid_domain_id= 2;
START TRANSACTION;
INSERT INTO t1 VALUES(10);
INSERT INTO t1 VALUES(11);
COMMIT;
SELECT * FROM t1;
i
1
2
3
4
5
6
7
8
9
10
11
# On slave
include/wait_for_slave_io_error.inc [errno=1595]
SELECT * FROM t1;
i
1
2
3
SET @@global.debug_dbug="-d";
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
SELECT * FROM t1;
i
1
2
3
10
11
# Case 3 : Start slave with IGNORE_DOMAIN_IDS=(1), then restart
# replication with IGNORE_DOMAIN_IDS=() after IO thread is
# killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_before_commit").
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
SET @@global.debug_dbug="+d,kill_slave_io_before_commit";
# On master
SET @@session.gtid_domain_id= 1;
START TRANSACTION;
INSERT INTO t1 VALUES(12);
INSERT INTO t1 VALUES(13);
COMMIT;
START TRANSACTION;
INSERT INTO t1 VALUES(14);
INSERT INTO t1 VALUES(15);
COMMIT;
SET @@session.gtid_domain_id= 2;
START TRANSACTION;
INSERT INTO t1 VALUES(16);
INSERT INTO t1 VALUES(17);
COMMIT;
SELECT * FROM t1;
i
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# On slave
include/wait_for_slave_io_error.inc [errno=1595]
SELECT * FROM t1;
i
1
2
3
10
11
SET @@global.debug_dbug="-d";
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
SELECT * FROM t1;
i
1
2
3
10
11
14
15
16
17
# Case 4 : Start slave with IGNORE_DOMAIN_IDS=(1), then restart
# replication with IGNORE_DOMAIN_IDS=() after IO thread is
# killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_after_2_events").
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
SET @@global.debug_dbug="+d,kill_slave_io_after_2_events";
# On master
SET @@session.gtid_domain_id= 1;
START TRANSACTION;
INSERT INTO t1 VALUES(18);
INSERT INTO t1 VALUES(19);
COMMIT;
START TRANSACTION;
INSERT INTO t1 VALUES(20);
INSERT INTO t1 VALUES(21);
COMMIT;
SET @@session.gtid_domain_id= 2;
START TRANSACTION;
INSERT INTO t1 VALUES(22);
INSERT INTO t1 VALUES(23);
COMMIT;
SELECT * FROM t1;
i
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# On slave
include/wait_for_slave_io_error.inc [errno=1595]
SELECT * FROM t1;
i
1
2
3
10
11
14
15
16
17
SET @@global.debug_dbug="-d";
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) : 1
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
SELECT * FROM t1;
i
1
2
3
10
11
14
15
16
17
20
21
22
23
# Case 5 : Start slave with IGNORE_DOMAIN_IDS=(), then restart
# replication with IGNORE_DOMAIN_IDS=(1) after IO thread is
# killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_after_2_events").
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
SET @@global.debug_dbug="+d,kill_slave_io_after_2_events";
# On master
SET @@session.gtid_domain_id= 1;
START TRANSACTION;
INSERT INTO t1 VALUES(24);
INSERT INTO t1 VALUES(25);
COMMIT;
START TRANSACTION;
INSERT INTO t1 VALUES(26);
INSERT INTO t1 VALUES(27);
COMMIT;
SET @@session.gtid_domain_id= 2;
START TRANSACTION;
INSERT INTO t1 VALUES(28);
INSERT INTO t1 VALUES(29);
COMMIT;
SELECT * FROM t1;
i
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# On slave
include/wait_for_slave_io_error.inc [errno=1595]
SELECT * FROM t1;
i
1
2
3
10
11
14
15
16
17
20
21
22
23
SET @@global.debug_dbug="-d";
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
SELECT * FROM t1;
i
1
2
3
10
11
14
15
16
17
20
21
22
23
28
29
# On master
DROP TABLE t1;
# On slave
include/stop_slave.inc
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=();
include/start_slave.inc
include/rpl_end.inc
include/master-slave.inc
[connection master]
# On master
call mtr.add_suppression("mysqld: Table './mysql/gtid_slave_pos' is marked as crashed and should be repaired");
call mtr.add_suppression("Checking table: './mysql/gtid_slave_pos'");
call mtr.add_suppression("mysql.gtid_slave_pos: 1 client is using or hasn't closed the table properly");
SET @@session.gtid_domain_id= 0;
create table ti (a int auto_increment primary key) engine=innodb;
create table tm (a int auto_increment primary key) engine=myisam;
insert into ti set a=null;
insert into tm set a=null;
# On slave
include/stop_slave.inc
select * from ti;
a
1
select * from tm;
a
1
# On master
SET @@session.gtid_domain_id= 1;
begin;
insert into ti set a=null;
insert into tm set a=null;
commit;
SET @@session.gtid_domain_id= 0;
insert into ti set a=null;
insert into tm set a=null;
set @@global.debug_dbug="+d,crash_before_send_xid";
# On slave
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
# On master
include/rpl_start_server.inc [server_number=1]
# Master has restarted successfully
set @@global.debug_dbug="-d";
# On slave
include/stop_slave.inc
include/start_slave.inc
select * from ti;
a
1
3
select * from tm;
a
1
3
# On master
drop table ti;
drop table tm;
# On slave
include/stop_slave.inc
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=NO;
include/start_slave.inc
include/rpl_end.inc
include/rpl_init.inc [topology=1->2]
# On slave
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
include/stop_slave.inc
SET GLOBAL slave_parallel_threads=10;
# On slave
CHANGE MASTER TO master_use_gtid=slave_pos, DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=();
include/start_slave.inc
# On master
SELECT @@session.gtid_domain_id;
@@session.gtid_domain_id
0
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM;
CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
# On slave
# New connection 'con_temp1'
LOCK TABLE t1 WRITE;
# On master
SET @@session.gtid_domain_id=1;
INSERT INTO t1 VALUES (2);
SET @@session.gtid_domain_id=0;
INSERT INTO t2 VALUES (2);
INSERT INTO t2 VALUES (3);
BEGIN;
INSERT INTO t2 VALUES (4);
INSERT INTO t2 VALUES (5);
COMMIT;
INSERT INTO t2 VALUES (6);
# On slave
SELECT * FROM t2 ORDER by a;
a
1
2
3
4
5
6
# On con_temp1
SELECT * FROM t1;
a
1
UNLOCK TABLES;
# On slave
SELECT * FROM t1 ORDER BY a;
a
1
2
# On slave
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) : 1
IGNORE_DOMAIN_IDS (AFTER) :
# On slave
# On con_temp1
LOCK TABLE t1 WRITE;
# On master
SET @@session.gtid_domain_id=0;
INSERT INTO t1 VALUES (3);
SET @@session.gtid_domain_id=1;
INSERT INTO t2 VALUES (7);
INSERT INTO t2 VALUES (8);
BEGIN;
INSERT INTO t2 VALUES (9);
INSERT INTO t2 VALUES (10);
COMMIT;
INSERT INTO t2 VALUES (11);
# On slave
SELECT * FROM t2 ORDER by a;
a
1
2
3
4
5
6
7
8
9
10
11
# On con_temp1
SELECT * FROM t1;
a
1
2
UNLOCK TABLES;
# On slave
SELECT * FROM t1 ORDER BY a;
a
1
2
# On slave
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) : 1
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
# On slave
# On con_temp1
LOCK TABLE t1 WRITE;
# On master
SET @@session.gtid_domain_id=1;
INSERT INTO t1 VALUES (4);
SET @@session.gtid_domain_id=0;
INSERT INTO t2 VALUES (12);
INSERT INTO t2 VALUES (13);
BEGIN;
INSERT INTO t2 VALUES (14);
INSERT INTO t2 VALUES (15);
COMMIT;
INSERT INTO t2 VALUES (16);
# On slave
SELECT * FROM t2 ORDER by a;
a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# On con_temp1
SELECT * FROM t1;
a
1
2
UNLOCK TABLES;
# On slave
SELECT * FROM t1 ORDER BY a;
a
1
2
SELECT * FROM t2;
a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Restore original settings.
# On master
SET @@session.gtid_domain_id=0;
DROP TABLE t1, t2;
# On slave
include/stop_slave.inc
SET GLOBAL slave_parallel_threads= @old_parallel_threads;
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=();
include/start_slave.inc
include/rpl_end.inc
include/master-slave.inc
[connection master]
# On slave
include/stop_slave.inc
DO_DOMAIN_IDS (BEFORE) :
IGNORE_DOMAIN_IDS (BEFORE) :
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) : 1
# On master
SET @@session.gtid_domain_id= 0;
CREATE TABLE t1(i INT);
CREATE TABLE t2(i INT);
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
i
1
SET @@session.gtid_domain_id= 1;
INSERT INTO t2 VALUES(1);
SELECT * FROM t2;
i
1
# On slave
SELECT * FROM t1;
i
1
SELECT * FROM t2;
i
include/rpl_restart_server.inc [server_number=2]
# On slave
DO_DOMAIN_IDS (AFTER RESTART) :
IGNORE_DOMAIN_IDS (AFTER RESTART) : 1
CHANGE MASTER TO IGNORE_DOMAIN_IDS=();
include/start_slave.inc
DO_DOMAIN_IDS (AFTER) :
IGNORE_DOMAIN_IDS (AFTER) :
SELECT * FROM t1;
i
1
SELECT * FROM t2;
i
# On master
SET @@session.gtid_domain_id= 0;
DROP TABLE t1, t2;
include/rpl_end.inc
This diff is collapsed.
This diff is collapsed.
--source include/have_innodb.inc
--source include/have_debug.inc
# Valgrind does not work well with test that crashes the server
--source include/not_valgrind.inc
--source include/master-slave.inc
--echo # On master
connection master;
call mtr.add_suppression("mysqld: Table './mysql/gtid_slave_pos' is marked as crashed and should be repaired");
call mtr.add_suppression("Checking table: './mysql/gtid_slave_pos'");
call mtr.add_suppression("mysql.gtid_slave_pos: 1 client is using or hasn't closed the table properly");
SET @@session.gtid_domain_id= 0;
create table ti (a int auto_increment primary key) engine=innodb;
create table tm (a int auto_increment primary key) engine=myisam;
insert into ti set a=null;
insert into tm set a=null;
save_master_pos;
--echo # On slave
connection slave;
sync_with_master;
--source include/stop_slave.inc
select * from ti;
select * from tm;
--echo # On master
connection master;
SET @@session.gtid_domain_id= 1;
begin;
insert into ti set a=null;
insert into tm set a=null;
commit;
SET @@session.gtid_domain_id= 0;
insert into ti set a=null;
insert into tm set a=null;
set @@global.debug_dbug="+d,crash_before_send_xid";
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--echo # On slave
connection slave;
let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before
--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before
# IGNORE_DOMAIN_IDS=(1)
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
--source include/start_slave.inc
let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after
--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after
--echo # On master
connection master;
--source include/wait_until_disconnected.inc
--enable_reconnect
--let $rpl_server_number=1
--source include/rpl_start_server.inc
#--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--echo # Master has restarted successfully
set @@global.debug_dbug="-d";
save_master_pos;
--echo # On slave
--connection slave
--source include/stop_slave.inc
--source include/start_slave.inc
sync_with_master;
select * from ti;
select * from tm;
# Cleanup
--echo # On master
--connection master
drop table ti;
drop table tm;
sync_slave_with_master;
--echo # On slave
--connection slave
--source include/stop_slave.inc
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=NO;
--source include/start_slave.inc
--source include/rpl_end.inc
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--let $rpl_topology=1->2
--source include/rpl_init.inc
--echo # On slave
--connection server_2
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
--source include/stop_slave.inc
SET GLOBAL slave_parallel_threads=10;
##### Case 0 : When both DO_DOMAIN_IDS and IGNORE_DOMAIN_IDS are empty.
--echo # On slave
--connection server_2
CHANGE MASTER TO master_use_gtid=slave_pos, DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=();
--source include/start_slave.inc
--echo # On master
--connection server_1
SELECT @@session.gtid_domain_id;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM;
CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (1);
--save_master_pos
--echo # On slave
--connection server_2
--sync_with_master
--echo # New connection 'con_temp1'
# Block the table t1 to simulate a replicated query taking a long time.
--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,)
LOCK TABLE t1 WRITE;
--echo # On master
--connection server_1
SET @@session.gtid_domain_id=1;
# This query will be blocked on the slave until UNLOCK TABLES.
INSERT INTO t1 VALUES (2);
SET @@session.gtid_domain_id=0;
# These t2 queries can be replicated in parallel with the prior t1 query, as
# they are in a separate replication domain.
INSERT INTO t2 VALUES (2);
INSERT INTO t2 VALUES (3);
BEGIN;
INSERT INTO t2 VALUES (4);
INSERT INTO t2 VALUES (5);
COMMIT;
INSERT INTO t2 VALUES (6);
--echo # On slave
--connection server_2
--let $wait_condition= SELECT COUNT(*) = 6 FROM t2
--source include/wait_condition.inc
SELECT * FROM t2 ORDER by a;
--echo # On con_temp1
--connection con_temp1
SELECT * FROM t1;
UNLOCK TABLES;
--echo # On slave
--connection server_2
--let $wait_condition= SELECT COUNT(*) = 2 FROM t1
--source include/wait_condition.inc
SELECT * FROM t1 ORDER BY a;
##### Case 1 : When DO_DOMAIN_IDS=(1)
--echo # On slave
--connection server_2
--source include/stop_slave.inc
let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before
--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before
# Replicate events belonging to "domain_id 1".
CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
--source include/start_slave.inc
sync_with_master;
let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after
--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after
--echo # On slave
--connection server_2
--sync_with_master
--echo # On con_temp1
# Block the table t1 to simulate a replicated query taking a long time.
--connection con_temp1
LOCK TABLE t1 WRITE;
--echo # On master
--connection server_1
SET @@session.gtid_domain_id=0;
# This query will be blocked on the slave until UNLOCK TABLES.
# But, since DO_DOMAIN_IDS=(1), it will be filtered out on slave.
INSERT INTO t1 VALUES (3);
SET @@session.gtid_domain_id=1;
# These t2 queries can be replicated in parallel with the prior t1 query, as
# they are in a separate replication domain.
INSERT INTO t2 VALUES (7);
INSERT INTO t2 VALUES (8);
BEGIN;
INSERT INTO t2 VALUES (9);
INSERT INTO t2 VALUES (10);
COMMIT;
INSERT INTO t2 VALUES (11);
--echo # On slave
--connection server_2
--let $wait_condition= SELECT COUNT(*) = 11 FROM t2
--source include/wait_condition.inc
SELECT * FROM t2 ORDER by a;
--echo # On con_temp1
--connection con_temp1
SELECT * FROM t1;
UNLOCK TABLES;
--echo # On slave
--connection server_2
--let $wait_condition= SELECT COUNT(*) = 2 FROM t1
--source include/wait_condition.inc
SELECT * FROM t1 ORDER BY a;
##### Case 2 : When IGNORE_DOMAIN_IDS=(1)
--echo # On slave
--connection server_2
--source include/stop_slave.inc
let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before
--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before
# Replicate events belonging to "domain_id 1".
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
--source include/start_slave.inc
sync_with_master;
let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after
--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after
--echo # On slave
--connection server_2
--sync_with_master
--echo # On con_temp1
# Block the table t1 to simulate a replicated query taking a long time.
--connection con_temp1
LOCK TABLE t1 WRITE;
--echo # On master
--connection server_1
SET @@session.gtid_domain_id=1;
# This query will be blocked on the slave until UNLOCK TABLES. However, since
# IGNORE_DOMAIN_IDS=(1), it will be filtered out on slave.
INSERT INTO t1 VALUES (4);
SET @@session.gtid_domain_id=0;
# These t2 queries can be replicated in parallel with the prior t1 query, as
# they are in a separate replication domain.
INSERT INTO t2 VALUES (12);
INSERT INTO t2 VALUES (13);
BEGIN;
INSERT INTO t2 VALUES (14);
INSERT INTO t2 VALUES (15);
COMMIT;
INSERT INTO t2 VALUES (16);
--echo # On slave
--connection server_2
--let $wait_condition= SELECT COUNT(*) = 16 FROM t2
--source include/wait_condition.inc
SELECT * FROM t2 ORDER by a;
--echo # On con_temp1
--connection con_temp1
SELECT * FROM t1;
UNLOCK TABLES;
--echo # On slave
--connection server_2
--let $wait_condition= SELECT COUNT(*) = 2 FROM t1
--source include/wait_condition.inc
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2;
--echo # Restore original settings.
--echo # On master
--connection server_1
SET @@session.gtid_domain_id=0;
DROP TABLE t1, t2;
--save_master_pos
--echo # On slave
--connection server_2
--sync_with_master
--source include/stop_slave.inc
SET GLOBAL slave_parallel_threads= @old_parallel_threads;
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=();
--source include/start_slave.inc
--source include/rpl_end.inc
--source include/master-slave.inc
#
# Test for domain-id based filter on slave restart in GTID-mode.
#
--echo # On slave
connection slave;
source include/stop_slave.inc;
let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before
--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before
# Ignore events belonging to "domain_id 1".
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos;
source include/start_slave.inc;
let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after
--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after
--echo # On master
connection master;
SET @@session.gtid_domain_id= 0;
CREATE TABLE t1(i INT);
CREATE TABLE t2(i INT);
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
SET @@session.gtid_domain_id= 1;
# the following will get filtered out.
INSERT INTO t2 VALUES(1);
SELECT * FROM t2;
sync_slave_with_master;
--echo # On slave
connection slave;
SELECT * FROM t1;
SELECT * FROM t2;
# restart the slave
--let $rpl_server_number= 2
--source include/rpl_restart_server.inc
--echo # On slave
# Replicate_Do_Domain_Ids/Replicate_Ignore_Domain_Ids should reinitialize
# properly on restart.
connection slave;
let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (AFTER RESTART) : $do_domain_ids_after
--echo IGNORE_DOMAIN_IDS (AFTER RESTART) : $ignore_domain_ids_after
# Now, lets clear IGNORE_DOMAIN_IDS.
CHANGE MASTER TO IGNORE_DOMAIN_IDS=();
--source include/start_slave.inc
let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after
--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after
SELECT * FROM t1;
SELECT * FROM t2;
--echo # On master
connection master;
SET @@session.gtid_domain_id= 0;
DROP TABLE t1, t2;
sync_slave_with_master;
--source include/rpl_end.inc
......@@ -195,6 +195,7 @@ static SYMBOL symbols[] = {
{ "DIV", SYM(DIV_SYM)},
{ "DO", SYM(DO_SYM)},
{ "DOUBLE", SYM(DOUBLE_SYM)},
{ "DO_DOMAIN_IDS", SYM(DO_DOMAIN_IDS_SYM)},
{ "DROP", SYM(DROP)},
{ "DUAL", SYM(DUAL_SYM)},
{ "DUMPFILE", SYM(DUMPFILE)},
......@@ -274,6 +275,7 @@ static SYMBOL symbols[] = {
{ "IDENTIFIED", SYM(IDENTIFIED_SYM)},
{ "IF", SYM(IF_SYM)},
{ "IGNORE", SYM(IGNORE_SYM)},
{ "IGNORE_DOMAIN_IDS", SYM(IGNORE_DOMAIN_IDS_SYM)},
{ "IGNORE_SERVER_IDS", SYM(IGNORE_SERVER_IDS_SYM)},
{ "IMPORT", SYM(IMPORT)},
{ "IN", SYM(IN_SYM)},
......
......@@ -201,7 +201,7 @@ struct rpl_slave_state
(domain_id, server_id) pair.
This will be logged at the start of the next binlog file as a
Gtid_list_log_event; this way, it is easy to find the binlog file
containing a gigen GTID, by simply scanning backwards from the newest
containing a given GTID, by simply scanning backwards from the newest
one until a lower seq_no is found in the Gtid_list_log_event at the
start of a binlog for the given domain_id and server_id.
......
This diff is collapsed.
......@@ -26,6 +26,111 @@
typedef struct st_mysql MYSQL;
/**
Domain id based filter to handle DO_DOMAIN_IDS and IGNORE_DOMAIN_IDS used to
set filtering on replication slave based on event's GTID domain_id.
*/
class Domain_id_filter
{
private:
/*
Flag to tell whether the events in the current GTID group get written to
the relay log. It is set according to the domain_id based filtering rule
on every GTID_EVENT and reset at the end of current GTID event group.
*/
bool m_filter;
/*
DO_DOMAIN_IDS (0):
Ignore all the events which do not belong to any of the domain ids in the
list.
IGNORE_DOMAIN_IDS (1):
Ignore the events which belong to one of the domain ids in the list.
*/
DYNAMIC_ARRAY m_domain_ids[2];
public:
/* domain id list types */
enum enum_list_type {
DO_DOMAIN_IDS= 0,
IGNORE_DOMAIN_IDS
};
Domain_id_filter();
~Domain_id_filter();
/*
Returns whether the current group needs to be filtered.
*/
bool is_group_filtered() { return m_filter; }
/*
Checks whether the group with the specified domain_id needs to be
filtered and updates m_filter flag accordingly.
*/
void do_filter(ulong domain_id);
/*
Reset m_filter. It should be called when IO thread receives COMMIT_EVENT or
XID_EVENT.
*/
void reset_filter();
/*
Update the do/ignore domain id filter lists.
@param do_ids [IN] domain ids to be kept
@param ignore_ids [IN] domain ids to be filtered out
@param using_gtid [IN] use GTID?
@retval false Success
true Error
*/
bool update_ids(DYNAMIC_ARRAY *do_ids, DYNAMIC_ARRAY *ignore_ids,
bool using_gtid);
/*
Serialize and store the ids from domain id lists into the thd's protocol
buffer.
@param thd [IN] thread handler
@retval void
*/
void store_ids(THD *thd);
/*
Initialize the given domain id list (DYNAMIC_ARRAY) with the
space-separated list of numbers from the specified IO_CACHE where
the first number is the total number of entries to follows.
@param f [IN] IO_CACHE file
@param type [IN] domain id list type
@retval false Success
true Error
*/
bool init_ids(IO_CACHE *f, enum_list_type type);
/*
Return the elements of the give domain id list type as string.
@param type [IN] domain id list type
@retval a string buffer storing the total number
of elements followed by the individual
elements (space-separated) in the
specified list.
Note: Its caller's responsibility to free the returned string buffer.
*/
char *as_string(enum_list_type type);
};
/*****************************************************************************
Replication IO Thread
......@@ -110,6 +215,13 @@ class Master_info : public Slave_reporting_capability
uint connect_retry;
#ifndef DBUG_OFF
int events_till_disconnect;
/*
The following are auxiliary DBUG variables used to kill IO thread in the
middle of a group/transaction (see "kill_slave_io_after_2_events").
*/
bool dbug_do_disconnect;
int dbug_event_counter;
#endif
bool inited;
volatile bool abort_slave;
......@@ -178,7 +290,11 @@ class Master_info : public Slave_reporting_capability
uint64 gtid_reconnect_event_skip_count;
/* gtid_event_seen is false until we receive first GTID event from master. */
bool gtid_event_seen;
/* domain-id based filter */
Domain_id_filter domain_id_filter;
};
int init_master_info(Master_info* mi, const char* master_info_fname,
const char* slave_info_fname,
bool abort_if_no_master_info_file,
......@@ -187,8 +303,9 @@ void end_master_info(Master_info* mi);
int flush_master_info(Master_info* mi,
bool flush_relay_log_cache,
bool need_lock_relay_log);
int change_master_server_id_cmp(ulong *id1, ulong *id2);
void copy_filter_setting(Rpl_filter* dst_filter, Rpl_filter* src_filter);
void update_change_master_ids(DYNAMIC_ARRAY *new_ids, DYNAMIC_ARRAY *old_ids);
void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids);
/*
Multi master are handled trough this struct.
......
......@@ -1202,7 +1202,6 @@ int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
DBUG_RETURN(1);
}
/*
when moving these functions to mysys, don't forget to
remove slave.cc from libmysqld/CMakeLists.txt
......@@ -1258,6 +1257,7 @@ int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val)
going to ignore (to not log them in the relay log).
Items being read are supposed to be decimal output of values of a
type shorter or equal of @c long and separated by the single space.
It also used to restore DO_DOMAIN_IDS & IGNORE_DOMAIN_IDS lists.
@param arr @c DYNAMIC_ARRAY pointer to storage for servers id
@param f @c IO_CACHE pointer to the source file
......@@ -1278,7 +1278,7 @@ int init_dynarray_intvar_from_file(DYNAMIC_ARRAY* arr, IO_CACHE* f)
if ((read_size= my_b_gets(f, buf_act, sizeof(buf))) == 0)
{
return 0; // no line in master.info
DBUG_RETURN(0); // no line in master.info
}
if (read_size + 1 == sizeof(buf) && buf[sizeof(buf) - 2] != '\n')
{
......@@ -2581,6 +2581,10 @@ static bool send_show_master_info_header(THD *thd, bool full,
field_list.push_back(new Item_empty_string("Using_Gtid",
sizeof("Current_Pos")-1));
field_list.push_back(new Item_empty_string("Gtid_IO_Pos", 30));
field_list.push_back(new Item_empty_string("Replicate_Do_Domain_Ids",
FN_REFLEN));
field_list.push_back(new Item_empty_string("Replicate_Ignore_Domain_Ids",
FN_REFLEN));
if (full)
{
field_list.push_back(new Item_return_int("Retried_transactions",
......@@ -2762,29 +2766,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full,
// Last_SQL_Error
protocol->store(mi->rli.last_error().message, &my_charset_bin);
// Replicate_Ignore_Server_Ids
{
char buff[FN_REFLEN];
ulong i, cur_len;
for (i= 0, buff[0]= 0, cur_len= 0;
i < mi->ignore_server_ids.elements; i++)
{
ulong s_id, slen;
char sbuff[FN_REFLEN];
get_dynamic(&mi->ignore_server_ids, (uchar*) &s_id, i);
slen= sprintf(sbuff, (i==0? "%lu" : ", %lu"), s_id);
if (cur_len + slen + 4 > FN_REFLEN)
{
/*
break the loop whenever remained space could not fit
ellipses on the next cycle
*/
sprintf(buff + cur_len, "...");
break;
}
cur_len += sprintf(buff + cur_len, "%s", sbuff);
}
protocol->store(buff, &my_charset_bin);
}
prot_store_ids(thd, &mi->ignore_server_ids);
// Master_Server_id
protocol->store((uint32) mi->master_id);
// Master_Ssl_Crl
......@@ -2798,6 +2780,10 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full,
mi->gtid_current_pos.to_string(&tmp);
protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
}
// Replicate_Do_Domain_Ids & Replicate_Ignore_Domain_Ids
mi->domain_id_filter.store_ids(thd);
if (full)
{
protocol->store((uint32) mi->rli.retried_trans);
......@@ -3784,6 +3770,7 @@ pthread_handler_t handle_slave_io(void *arg)
rpl_io_thread_info io_info;
#ifndef DBUG_OFF
uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0;
mi->dbug_do_disconnect= false;
#endif
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init();
......@@ -5587,6 +5574,12 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
case GTID_EVENT:
{
DBUG_EXECUTE_IF("kill_slave_io_after_2_events",
{
mi->dbug_do_disconnect= true;
mi->dbug_event_counter= 2;
};);
uchar gtid_flag;
if (Gtid_log_event::peek(buf, event_len, checksum_alg,
......@@ -5656,6 +5649,10 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
mi->last_queued_gtid= event_gtid;
mi->last_queued_gtid_standalone=
(gtid_flag & Gtid_log_event::FL_STANDALONE) != 0;
/* Should filter all the subsequent events in the current GTID group? */
mi->domain_id_filter.do_filter(event_gtid.domain_id);
++mi->events_queued_since_last_gtid;
inc_pos= event_len;
}
......@@ -5663,6 +5660,47 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
default:
default_action:
DBUG_EXECUTE_IF("kill_slave_io_after_2_events",
{
if (mi->dbug_do_disconnect &&
(((uchar)buf[EVENT_TYPE_OFFSET] == QUERY_EVENT) ||
((uchar)buf[EVENT_TYPE_OFFSET] == TABLE_MAP_EVENT))
&& (--mi->dbug_event_counter == 0))
{
error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
mi->dbug_do_disconnect= false; /* Safety */
goto err;
}
};);
DBUG_EXECUTE_IF("kill_slave_io_before_commit",
{
if ((uchar)buf[EVENT_TYPE_OFFSET] == XID_EVENT ||
((uchar)buf[EVENT_TYPE_OFFSET] == QUERY_EVENT &&
Query_log_event::peek_is_commit_rollback(buf, event_len,
checksum_alg)))
{
error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
goto err;
}
};);
if (mi->using_gtid != Master_info::USE_GTID_NO &&
mi->domain_id_filter.is_group_filtered() &&
mi->events_queued_since_last_gtid > 0 &&
((mi->last_queued_gtid_standalone &&
!Log_event::is_part_of_group((Log_event_type)(uchar)
buf[EVENT_TYPE_OFFSET])) ||
(!mi->last_queued_gtid_standalone &&
((uchar)buf[EVENT_TYPE_OFFSET] == XID_EVENT ||
((uchar)buf[EVENT_TYPE_OFFSET] == QUERY_EVENT &&
Query_log_event::peek_is_commit_rollback(buf, event_len,
checksum_alg))))))
{
/* Reset the domain_id_filter flag. */
mi->domain_id_filter.reset_filter();
}
if (mi->using_gtid != Master_info::USE_GTID_NO && mi->gtid_event_seen)
{
if (unlikely(mi->gtid_reconnect_event_skip_count))
......@@ -5765,7 +5803,15 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
(s_id != mi->master_id ||
/* for the master meta information is necessary */
(buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT &&
buf[EVENT_TYPE_OFFSET] != ROTATE_EVENT))))
buf[EVENT_TYPE_OFFSET] != ROTATE_EVENT))) ||
/*
Check whether it needs to be filtered based on domain_id
(DO_DOMAIN_IDS/IGNORE_DOMAIN_IDS).
*/
(mi->domain_id_filter.is_group_filtered() &&
Log_event::is_group_event((Log_event_type)(uchar)
buf[EVENT_TYPE_OFFSET])))
{
/*
Do not write it to the relay log.
......@@ -5842,16 +5888,20 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
}
skip_relay_logging:
err:
if (unlock_data_lock)
mysql_mutex_unlock(&mi->data_lock);
DBUG_PRINT("info", ("error: %d", error));
if (error)
/*
Do not print ER_SLAVE_RELAY_LOG_WRITE_FAILURE error here, as the caller
handle_slave_io() prints it on return.
*/
if (error && error != ER_SLAVE_RELAY_LOG_WRITE_FAILURE)
mi->report(ERROR_LEVEL, error, NULL, ER(error),
(error == ER_SLAVE_RELAY_LOG_WRITE_FAILURE)?
"could not queue event from master" :
error_msg.ptr());
DBUG_RETURN(error);
}
......
......@@ -217,6 +217,8 @@ typedef struct st_lex_server_options
struct LEX_MASTER_INFO
{
DYNAMIC_ARRAY repl_ignore_server_ids;
DYNAMIC_ARRAY repl_do_domain_ids;
DYNAMIC_ARRAY repl_ignore_domain_ids;
char *host, *user, *password, *log_file_name;
char *ssl_key, *ssl_cert, *ssl_ca, *ssl_capath, *ssl_cipher;
char *ssl_crl, *ssl_crlpath;
......@@ -234,7 +236,8 @@ struct LEX_MASTER_INFO
changed variable or if it should be left at old value
*/
enum {LEX_MI_UNCHANGED, LEX_MI_DISABLE, LEX_MI_ENABLE}
ssl, ssl_verify_server_cert, heartbeat_opt, repl_ignore_server_ids_opt;
ssl, ssl_verify_server_cert, heartbeat_opt, repl_ignore_server_ids_opt,
repl_do_domain_ids_opt, repl_ignore_domain_ids_opt;
enum {
LEX_GTID_UNCHANGED, LEX_GTID_NO, LEX_GTID_CURRENT_POS, LEX_GTID_SLAVE_POS
} use_gtid_opt;
......@@ -244,16 +247,25 @@ struct LEX_MASTER_INFO
bzero(this, sizeof(*this));
my_init_dynamic_array(&repl_ignore_server_ids,
sizeof(::server_id), 0, 16, MYF(0));
my_init_dynamic_array(&repl_do_domain_ids,
sizeof(ulong), 0, 16, MYF(0));
my_init_dynamic_array(&repl_ignore_domain_ids,
sizeof(ulong), 0, 16, MYF(0));
}
void reset()
{
delete_dynamic(&repl_ignore_server_ids);
/* Free all the array elements. */
delete_dynamic(&repl_do_domain_ids);
delete_dynamic(&repl_ignore_domain_ids);
host= user= password= log_file_name= ssl_key= ssl_cert= ssl_ca=
ssl_capath= ssl_cipher= relay_log_name= 0;
pos= relay_log_pos= server_id= port= connect_retry= 0;
heartbeat_period= 0;
ssl= ssl_verify_server_cert= heartbeat_opt=
repl_ignore_server_ids_opt= LEX_MI_UNCHANGED;
repl_ignore_server_ids_opt= repl_do_domain_ids_opt=
repl_ignore_domain_ids_opt= LEX_MI_UNCHANGED;
gtid_pos_str= null_lex_str;
use_gtid_opt= LEX_GTID_UNCHANGED;
}
......
......@@ -2429,6 +2429,16 @@ impossible position";
}
});
/* Abort server before it sends the XID_EVENT */
DBUG_EXECUTE_IF("crash_before_send_xid",
{
if (event_type == XID_EVENT)
{
my_sleep(2000000);
DBUG_SUICIDE();
}
});
/* reset transmit packet for next loop */
if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg))
goto err;
......@@ -3224,6 +3234,8 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
char relay_log_info_file_tmp[FN_REFLEN];
my_off_t saved_log_pos;
LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
DYNAMIC_ARRAY *do_ids, *ignore_ids;
DBUG_ENTER("change_master");
mysql_mutex_assert_owner(&LOCK_active_mi);
......@@ -3355,33 +3367,30 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
mi->heartbeat_period= (float) MY_MIN(SLAVE_MAX_HEARTBEAT_PERIOD,
(slave_net_timeout/2.0));
mi->received_heartbeats= 0; // counter lives until master is CHANGEd
/*
reset the last time server_id list if the current CHANGE MASTER
Reset the last time server_id list if the current CHANGE MASTER
is mentioning IGNORE_SERVER_IDS= (...)
*/
if (lex_mi->repl_ignore_server_ids_opt == LEX_MASTER_INFO::LEX_MI_ENABLE)
reset_dynamic(&mi->ignore_server_ids);
for (uint i= 0; i < lex_mi->repl_ignore_server_ids.elements; i++)
{
ulong s_id;
get_dynamic(&lex_mi->repl_ignore_server_ids, (uchar*) &s_id, i);
if (s_id == global_system_variables.server_id && replicate_same_server_id)
/* Check if the list contains replicate_same_server_id */
for (uint i= 0; i < lex_mi->repl_ignore_server_ids.elements; i ++)
{
my_error(ER_SLAVE_IGNORE_SERVER_IDS, MYF(0), static_cast<int>(s_id));
ret= TRUE;
goto err;
}
else
{
if (bsearch((const ulong *) &s_id,
mi->ignore_server_ids.buffer,
mi->ignore_server_ids.elements, sizeof(ulong),
(int (*) (const void*, const void*))
change_master_server_id_cmp) == NULL)
insert_dynamic(&mi->ignore_server_ids, (uchar*) &s_id);
ulong s_id;
get_dynamic(&lex_mi->repl_ignore_server_ids, (uchar*) &s_id, i);
if (s_id == global_system_variables.server_id && replicate_same_server_id)
{
my_error(ER_SLAVE_IGNORE_SERVER_IDS, MYF(0), static_cast<int>(s_id));
ret= TRUE;
goto err;
}
}
/* All ok. Update the old server ids with the new ones. */
update_change_master_ids(&lex_mi->repl_ignore_server_ids,
&mi->ignore_server_ids);
}
sort_dynamic(&mi->ignore_server_ids, (qsort_cmp) change_master_server_id_cmp);
if (lex_mi->ssl != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
mi->ssl= (lex_mi->ssl == LEX_MASTER_INFO::LEX_MI_ENABLE);
......@@ -3437,6 +3446,27 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
lex_mi->relay_log_name || lex_mi->relay_log_pos)
mi->using_gtid= Master_info::USE_GTID_NO;
do_ids= ((lex_mi->repl_do_domain_ids_opt ==
LEX_MASTER_INFO::LEX_MI_ENABLE) ?
&lex_mi->repl_do_domain_ids : NULL);
ignore_ids= ((lex_mi->repl_ignore_domain_ids_opt ==
LEX_MASTER_INFO::LEX_MI_ENABLE) ?
&lex_mi->repl_ignore_domain_ids : NULL);
/*
Note: mi->using_gtid stores the previous state in case no MASTER_USE_GTID
is specified.
*/
if (mi->domain_id_filter.update_ids(do_ids, ignore_ids, mi->using_gtid))
{
my_error(ER_MASTER_INFO, MYF(0),
(int) lex_mi->connection_name.length,
lex_mi->connection_name.str);
ret= TRUE;
goto err;
}
/*
If user did specify neither host nor port nor any log name nor any log
pos, i.e. he specified only user/password/master_connect_retry, he probably
......
......@@ -1103,6 +1103,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DISTINCT /* SQL-2003-R */
%token DIV_SYM
%token DOUBLE_SYM /* SQL-2003-R */
%token DO_DOMAIN_IDS_SYM
%token DO_SYM
%token DROP /* SQL-2003-R */
%token DUAL_SYM
......@@ -1190,6 +1191,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token IDENTIFIED_SYM
%token IDENT_QUOTED
%token IF_SYM
%token IGNORE_DOMAIN_IDS_SYM
%token IGNORE_SYM
%token IGNORE_SERVER_IDS_SYM
%token IMPORT
......@@ -2228,6 +2230,14 @@ master_def:
{
Lex->mi.repl_ignore_server_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
}
| DO_DOMAIN_IDS_SYM EQ '(' do_domain_id_list ')'
{
Lex->mi.repl_do_domain_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
}
| IGNORE_DOMAIN_IDS_SYM EQ '(' ignore_domain_id_list ')'
{
Lex->mi.repl_ignore_domain_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
}
|
master_file_def
;
......@@ -2244,6 +2254,30 @@ ignore_server_id:
insert_dynamic(&Lex->mi.repl_ignore_server_ids, (uchar*) &($1));
}
do_domain_id_list:
/* Empty */
| do_domain_id
| do_domain_id_list ',' do_domain_id
;
do_domain_id:
ulong_num
{
insert_dynamic(&Lex->mi.repl_do_domain_ids, (uchar*) &($1));
}
ignore_domain_id_list:
/* Empty */
| ignore_domain_id
| ignore_domain_id_list ',' ignore_domain_id
;
ignore_domain_id:
ulong_num
{
insert_dynamic(&Lex->mi.repl_ignore_domain_ids, (uchar*) &($1));
}
master_file_def:
MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment