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) ...@@ -64,6 +64,8 @@ if ($tmp)
--echo Master_SSL_Crlpath # --echo Master_SSL_Crlpath #
--echo Using_Gtid No --echo Using_Gtid No
--echo Gtid_IO_Pos # --echo Gtid_IO_Pos #
--echo Replicate_Do_Domain_Ids
--echo Replicate_Ignore_Domain_Ids
} }
if (!$tmp) { if (!$tmp) {
# Note: after WL#5177, fields 13-18 shall not be filtered-out. # Note: after WL#5177, fields 13-18 shall not be filtered-out.
......
...@@ -84,17 +84,17 @@ MASTER 2.2 ...@@ -84,17 +84,17 @@ MASTER 2.2
# EOF # EOF
# #
show all slaves status; 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
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 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 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 include/wait_for_slave_to_start.inc
set default_master_connection = 'MASTER 2.2'; set default_master_connection = 'MASTER 2.2';
include/wait_for_slave_to_start.inc include/wait_for_slave_to_start.inc
set default_master_connection = ''; set default_master_connection = '';
show all slaves status; 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
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 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 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 # List of files matching '*info*' pattern
# after slave server restart # after slave server restart
......
...@@ -10,15 +10,15 @@ create table t1 (i int) engine=MyISAM; ...@@ -10,15 +10,15 @@ create table t1 (i int) engine=MyISAM;
insert into t1 values (1),(2); insert into t1 values (1),(2);
stop slave 'master1'; stop slave 'master1';
show slave 'master1' status; 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 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 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.000001
mysqld-relay-bin-master1.000002 mysqld-relay-bin-master1.000002
mysqld-relay-bin-master1.index mysqld-relay-bin-master1.index
reset slave 'master1'; reset slave 'master1';
show slave 'master1' status; 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 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 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; reset slave 'master1' all;
show slave 'master1' status; show slave 'master1' status;
ERROR HY000: There is no master connection 'master1' ERROR HY000: There is no master connection 'master1'
......
This diff is collapsed.
include/master-slave.inc include/master-slave.inc
[connection master] [connection master]
show slave status; 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; 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; 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 # 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[] = { ...@@ -195,6 +195,7 @@ static SYMBOL symbols[] = {
{ "DIV", SYM(DIV_SYM)}, { "DIV", SYM(DIV_SYM)},
{ "DO", SYM(DO_SYM)}, { "DO", SYM(DO_SYM)},
{ "DOUBLE", SYM(DOUBLE_SYM)}, { "DOUBLE", SYM(DOUBLE_SYM)},
{ "DO_DOMAIN_IDS", SYM(DO_DOMAIN_IDS_SYM)},
{ "DROP", SYM(DROP)}, { "DROP", SYM(DROP)},
{ "DUAL", SYM(DUAL_SYM)}, { "DUAL", SYM(DUAL_SYM)},
{ "DUMPFILE", SYM(DUMPFILE)}, { "DUMPFILE", SYM(DUMPFILE)},
...@@ -274,6 +275,7 @@ static SYMBOL symbols[] = { ...@@ -274,6 +275,7 @@ static SYMBOL symbols[] = {
{ "IDENTIFIED", SYM(IDENTIFIED_SYM)}, { "IDENTIFIED", SYM(IDENTIFIED_SYM)},
{ "IF", SYM(IF_SYM)}, { "IF", SYM(IF_SYM)},
{ "IGNORE", SYM(IGNORE_SYM)}, { "IGNORE", SYM(IGNORE_SYM)},
{ "IGNORE_DOMAIN_IDS", SYM(IGNORE_DOMAIN_IDS_SYM)},
{ "IGNORE_SERVER_IDS", SYM(IGNORE_SERVER_IDS_SYM)}, { "IGNORE_SERVER_IDS", SYM(IGNORE_SERVER_IDS_SYM)},
{ "IMPORT", SYM(IMPORT)}, { "IMPORT", SYM(IMPORT)},
{ "IN", SYM(IN_SYM)}, { "IN", SYM(IN_SYM)},
......
...@@ -201,7 +201,7 @@ struct rpl_slave_state ...@@ -201,7 +201,7 @@ struct rpl_slave_state
(domain_id, server_id) pair. (domain_id, server_id) pair.
This will be logged at the start of the next binlog file as a 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 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 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. start of a binlog for the given domain_id and server_id.
......
This diff is collapsed.
...@@ -26,6 +26,111 @@ ...@@ -26,6 +26,111 @@
typedef struct st_mysql MYSQL; 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 Replication IO Thread
...@@ -110,6 +215,13 @@ class Master_info : public Slave_reporting_capability ...@@ -110,6 +215,13 @@ class Master_info : public Slave_reporting_capability
uint connect_retry; uint connect_retry;
#ifndef DBUG_OFF #ifndef DBUG_OFF
int events_till_disconnect; 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 #endif
bool inited; bool inited;
volatile bool abort_slave; volatile bool abort_slave;
...@@ -178,7 +290,11 @@ class Master_info : public Slave_reporting_capability ...@@ -178,7 +290,11 @@ class Master_info : public Slave_reporting_capability
uint64 gtid_reconnect_event_skip_count; uint64 gtid_reconnect_event_skip_count;
/* gtid_event_seen is false until we receive first GTID event from master. */ /* gtid_event_seen is false until we receive first GTID event from master. */
bool gtid_event_seen; 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, int init_master_info(Master_info* mi, const char* master_info_fname,
const char* slave_info_fname, const char* slave_info_fname,
bool abort_if_no_master_info_file, bool abort_if_no_master_info_file,
...@@ -187,8 +303,9 @@ void end_master_info(Master_info* mi); ...@@ -187,8 +303,9 @@ void end_master_info(Master_info* mi);
int flush_master_info(Master_info* mi, int flush_master_info(Master_info* mi,
bool flush_relay_log_cache, bool flush_relay_log_cache,
bool need_lock_relay_log); 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 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. Multi master are handled trough this struct.
......
...@@ -1202,7 +1202,6 @@ int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, ...@@ -1202,7 +1202,6 @@ int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* /*
when moving these functions to mysys, don't forget to when moving these functions to mysys, don't forget to
remove slave.cc from libmysqld/CMakeLists.txt remove slave.cc from libmysqld/CMakeLists.txt
...@@ -1258,6 +1257,7 @@ int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val) ...@@ -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). going to ignore (to not log them in the relay log).
Items being read are supposed to be decimal output of values of a 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. 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 arr @c DYNAMIC_ARRAY pointer to storage for servers id
@param f @c IO_CACHE pointer to the source file @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) ...@@ -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) 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') 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, ...@@ -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", field_list.push_back(new Item_empty_string("Using_Gtid",
sizeof("Current_Pos")-1)); sizeof("Current_Pos")-1));
field_list.push_back(new Item_empty_string("Gtid_IO_Pos", 30)); 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) if (full)
{ {
field_list.push_back(new Item_return_int("Retried_transactions", 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, ...@@ -2762,29 +2766,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full,
// Last_SQL_Error // Last_SQL_Error
protocol->store(mi->rli.last_error().message, &my_charset_bin); protocol->store(mi->rli.last_error().message, &my_charset_bin);
// Replicate_Ignore_Server_Ids // Replicate_Ignore_Server_Ids
{ prot_store_ids(thd, &mi->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);
}
// Master_Server_id // Master_Server_id
protocol->store((uint32) mi->master_id); protocol->store((uint32) mi->master_id);
// Master_Ssl_Crl // Master_Ssl_Crl
...@@ -2798,6 +2780,10 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, ...@@ -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); mi->gtid_current_pos.to_string(&tmp);
protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin); 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) if (full)
{ {
protocol->store((uint32) mi->rli.retried_trans); protocol->store((uint32) mi->rli.retried_trans);
...@@ -3784,6 +3770,7 @@ pthread_handler_t handle_slave_io(void *arg) ...@@ -3784,6 +3770,7 @@ pthread_handler_t handle_slave_io(void *arg)
rpl_io_thread_info io_info; rpl_io_thread_info io_info;
#ifndef DBUG_OFF #ifndef DBUG_OFF
uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0; uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0;
mi->dbug_do_disconnect= false;
#endif #endif
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init(); my_thread_init();
...@@ -5587,6 +5574,12 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) ...@@ -5587,6 +5574,12 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
case GTID_EVENT: 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; uchar gtid_flag;
if (Gtid_log_event::peek(buf, event_len, checksum_alg, 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) ...@@ -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= event_gtid;
mi->last_queued_gtid_standalone= mi->last_queued_gtid_standalone=
(gtid_flag & Gtid_log_event::FL_STANDALONE) != 0; (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; ++mi->events_queued_since_last_gtid;
inc_pos= event_len; inc_pos= event_len;
} }
...@@ -5663,6 +5660,47 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) ...@@ -5663,6 +5660,47 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
default: default:
default_action: 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 (mi->using_gtid != Master_info::USE_GTID_NO && mi->gtid_event_seen)
{ {
if (unlikely(mi->gtid_reconnect_event_skip_count)) 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) ...@@ -5765,7 +5803,15 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
(s_id != mi->master_id || (s_id != mi->master_id ||
/* for the master meta information is necessary */ /* for the master meta information is necessary */
(buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT && (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. 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) ...@@ -5842,16 +5888,20 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
} }
skip_relay_logging: skip_relay_logging:
err: err:
if (unlock_data_lock) if (unlock_data_lock)
mysql_mutex_unlock(&mi->data_lock); mysql_mutex_unlock(&mi->data_lock);
DBUG_PRINT("info", ("error: %d", error)); 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), mi->report(ERROR_LEVEL, error, NULL, ER(error),
(error == ER_SLAVE_RELAY_LOG_WRITE_FAILURE)?
"could not queue event from master" :
error_msg.ptr()); error_msg.ptr());
DBUG_RETURN(error); DBUG_RETURN(error);
} }
......
...@@ -217,6 +217,8 @@ typedef struct st_lex_server_options ...@@ -217,6 +217,8 @@ typedef struct st_lex_server_options
struct LEX_MASTER_INFO struct LEX_MASTER_INFO
{ {
DYNAMIC_ARRAY repl_ignore_server_ids; 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 *host, *user, *password, *log_file_name;
char *ssl_key, *ssl_cert, *ssl_ca, *ssl_capath, *ssl_cipher; char *ssl_key, *ssl_cert, *ssl_ca, *ssl_capath, *ssl_cipher;
char *ssl_crl, *ssl_crlpath; char *ssl_crl, *ssl_crlpath;
...@@ -234,7 +236,8 @@ struct LEX_MASTER_INFO ...@@ -234,7 +236,8 @@ struct LEX_MASTER_INFO
changed variable or if it should be left at old value changed variable or if it should be left at old value
*/ */
enum {LEX_MI_UNCHANGED, LEX_MI_DISABLE, LEX_MI_ENABLE} 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 { enum {
LEX_GTID_UNCHANGED, LEX_GTID_NO, LEX_GTID_CURRENT_POS, LEX_GTID_SLAVE_POS LEX_GTID_UNCHANGED, LEX_GTID_NO, LEX_GTID_CURRENT_POS, LEX_GTID_SLAVE_POS
} use_gtid_opt; } use_gtid_opt;
...@@ -244,16 +247,25 @@ struct LEX_MASTER_INFO ...@@ -244,16 +247,25 @@ struct LEX_MASTER_INFO
bzero(this, sizeof(*this)); bzero(this, sizeof(*this));
my_init_dynamic_array(&repl_ignore_server_ids, my_init_dynamic_array(&repl_ignore_server_ids,
sizeof(::server_id), 0, 16, MYF(0)); 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() void reset()
{ {
delete_dynamic(&repl_ignore_server_ids); 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= host= user= password= log_file_name= ssl_key= ssl_cert= ssl_ca=
ssl_capath= ssl_cipher= relay_log_name= 0; ssl_capath= ssl_cipher= relay_log_name= 0;
pos= relay_log_pos= server_id= port= connect_retry= 0; pos= relay_log_pos= server_id= port= connect_retry= 0;
heartbeat_period= 0; heartbeat_period= 0;
ssl= ssl_verify_server_cert= heartbeat_opt= 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; gtid_pos_str= null_lex_str;
use_gtid_opt= LEX_GTID_UNCHANGED; use_gtid_opt= LEX_GTID_UNCHANGED;
} }
......
...@@ -2429,6 +2429,16 @@ impossible position"; ...@@ -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 */ /* reset transmit packet for next loop */
if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg)) if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg))
goto err; goto err;
...@@ -3224,6 +3234,8 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) ...@@ -3224,6 +3234,8 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
char relay_log_info_file_tmp[FN_REFLEN]; char relay_log_info_file_tmp[FN_REFLEN];
my_off_t saved_log_pos; my_off_t saved_log_pos;
LEX_MASTER_INFO* lex_mi= &thd->lex->mi; LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
DYNAMIC_ARRAY *do_ids, *ignore_ids;
DBUG_ENTER("change_master"); DBUG_ENTER("change_master");
mysql_mutex_assert_owner(&LOCK_active_mi); mysql_mutex_assert_owner(&LOCK_active_mi);
...@@ -3355,33 +3367,30 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) ...@@ -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, mi->heartbeat_period= (float) MY_MIN(SLAVE_MAX_HEARTBEAT_PERIOD,
(slave_net_timeout/2.0)); (slave_net_timeout/2.0));
mi->received_heartbeats= 0; // counter lives until master is CHANGEd 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= (...) is mentioning IGNORE_SERVER_IDS= (...)
*/ */
if (lex_mi->repl_ignore_server_ids_opt == LEX_MASTER_INFO::LEX_MI_ENABLE) 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; /* Check if the list contains replicate_same_server_id */
get_dynamic(&lex_mi->repl_ignore_server_ids, (uchar*) &s_id, i); for (uint i= 0; i < lex_mi->repl_ignore_server_ids.elements; 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)); ulong s_id;
ret= TRUE; get_dynamic(&lex_mi->repl_ignore_server_ids, (uchar*) &s_id, i);
goto err; if (s_id == global_system_variables.server_id && replicate_same_server_id)
} {
else my_error(ER_SLAVE_IGNORE_SERVER_IDS, MYF(0), static_cast<int>(s_id));
{ ret= TRUE;
if (bsearch((const ulong *) &s_id, goto err;
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);
} }
/* 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) if (lex_mi->ssl != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
mi->ssl= (lex_mi->ssl == LEX_MASTER_INFO::LEX_MI_ENABLE); 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) ...@@ -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) lex_mi->relay_log_name || lex_mi->relay_log_pos)
mi->using_gtid= Master_info::USE_GTID_NO; 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 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 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); ...@@ -1103,6 +1103,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DISTINCT /* SQL-2003-R */ %token DISTINCT /* SQL-2003-R */
%token DIV_SYM %token DIV_SYM
%token DOUBLE_SYM /* SQL-2003-R */ %token DOUBLE_SYM /* SQL-2003-R */
%token DO_DOMAIN_IDS_SYM
%token DO_SYM %token DO_SYM
%token DROP /* SQL-2003-R */ %token DROP /* SQL-2003-R */
%token DUAL_SYM %token DUAL_SYM
...@@ -1190,6 +1191,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -1190,6 +1191,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token IDENTIFIED_SYM %token IDENTIFIED_SYM
%token IDENT_QUOTED %token IDENT_QUOTED
%token IF_SYM %token IF_SYM
%token IGNORE_DOMAIN_IDS_SYM
%token IGNORE_SYM %token IGNORE_SYM
%token IGNORE_SERVER_IDS_SYM %token IGNORE_SERVER_IDS_SYM
%token IMPORT %token IMPORT
...@@ -2228,6 +2230,14 @@ master_def: ...@@ -2228,6 +2230,14 @@ master_def:
{ {
Lex->mi.repl_ignore_server_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE; 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 master_file_def
; ;
...@@ -2244,6 +2254,30 @@ ignore_server_id: ...@@ -2244,6 +2254,30 @@ ignore_server_id:
insert_dynamic(&Lex->mi.repl_ignore_server_ids, (uchar*) &($1)); 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_file_def:
MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys 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