summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/rpl/r/rpl_circular_semi_sync.result76
-rw-r--r--mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf11
-rw-r--r--mysql-test/suite/rpl/t/rpl_circular_semi_sync.test115
-rw-r--r--sql/slave.cc24
4 files changed, 217 insertions, 9 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result b/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result
new file mode 100644
index 00000000000..dcced9833ca
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_circular_semi_sync.result
@@ -0,0 +1,76 @@
+include/master-slave.inc
+[connection master]
+# Master server_1 and Slave server_2 initialiation ...
+connection server_2;
+include/stop_slave.inc
+connection server_1;
+set @@sql_log_bin = off;
+call mtr.add_suppression("Slave: An attempt was made to binlog GTID 10-1-1 which would create an out-of-order sequence number with existing GTID");
+set @@sql_log_bin = on;
+RESET MASTER;
+set @@session.gtid_domain_id=10;
+set @@global.rpl_semi_sync_master_enabled = 1;
+set @@global.rpl_semi_sync_master_wait_point=AFTER_SYNC;
+connection server_2;
+RESET MASTER;
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+set @@session.gtid_domain_id=20;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+# a 1948 warning is expected
+set @@global.gtid_slave_pos = "";
+Warnings:
+Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-1. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos
+CHANGE MASTER TO master_use_gtid= slave_pos;
+include/start_slave.inc
+# ... server_1 -> server_2 is set up
+connection server_1;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Innodb;
+INSERT INTO t1 VALUES (1);
+connection server_2;
+# Circular configuration server_2 -> server_1 initialiation ...
+connection server_1;
+# A. ... first when server_1 is in gtid strict mode...
+set @@global.gtid_strict_mode = true;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root', master_use_gtid=SLAVE_POS;
+# ... only for it to fail 'cos if its inconsistent (empty) slave's gtid state:
+SELECT @@global.gtid_slave_pos;
+@@global.gtid_slave_pos
+
+START SLAVE;
+include/wait_for_slave_sql_error.inc [errno=1950]
+# B. ... Resume on the circular setup with the server_id now in the non-strict mode ...
+set @@global.gtid_strict_mode = false;
+include/start_slave.inc
+# ... to have succeeded.
+connection server_2;
+INSERT INTO t1 VALUES (2);
+connection server_1;
+INSERT INTO t1 VALUES (3);
+connection server_2;
+# The gtid states on server_2 must be equal to ...
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+Variable_name Value
+gtid_binlog_pos 0-2-1,10-1-3,20-2-1
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+Variable_name Value
+gtid_slave_pos 0-2-1,10-1-3,20-2-1
+connection server_1;
+# ... the gtid states on server_1
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+Variable_name Value
+gtid_slave_pos 0-2-1,10-1-3,20-2-1
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+Variable_name Value
+gtid_binlog_pos 0-2-1,10-1-3,20-2-1
+# Cleanup
+connection server_1;
+include/stop_slave.inc
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+set @@global.rpl_semi_sync_master_wait_point=default;
+DROP TABLE t1;
+connection server_2;
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf
new file mode 100644
index 00000000000..be39fea91d8
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.cnf
@@ -0,0 +1,11 @@
+!include suite/rpl/rpl_1slave_base.cnf
+!include include/default_client.cnf
+
+
+[mysqld.1]
+log-slave-updates
+sync-binlog=1
+
+[mysqld.2]
+log-slave-updates
+sync-binlog=1
diff --git a/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test
new file mode 100644
index 00000000000..51fa5a242ea
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_circular_semi_sync.test
@@ -0,0 +1,115 @@
+# ==== References ====
+#
+# MDEV-27760 event may non stop replicate in circular semisync setup
+#
+--source include/have_innodb.inc
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+# The following tests prove
+# A. out-of-order gtid error when the stict gtid mode semisync slave
+# receives the same server-id gtid event inconsistent
+# (rpl_semi_sync_fail_over tests the consistent case) with its state;
+# B. in the non-strict mode the same server-id events remains ignored
+# by default as usual.
+#
+--echo # Master server_1 and Slave server_2 initialiation ...
+--connection server_2
+--source include/stop_slave.inc
+
+# Initial master
+--connection server_1
+set @@sql_log_bin = off;
+call mtr.add_suppression("Slave: An attempt was made to binlog GTID 10-1-1 which would create an out-of-order sequence number with existing GTID");
+set @@sql_log_bin = on;
+
+RESET MASTER;
+
+set @@session.gtid_domain_id=10;
+
+set @@global.rpl_semi_sync_master_enabled = 1;
+set @@global.rpl_semi_sync_master_wait_point=AFTER_SYNC;
+
+--connection server_2
+RESET MASTER;
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+
+set @@session.gtid_domain_id=20;
+
+set @@global.rpl_semi_sync_slave_enabled = 1;
+--echo # a 1948 warning is expected
+set @@global.gtid_slave_pos = "";
+CHANGE MASTER TO master_use_gtid= slave_pos;
+--source include/start_slave.inc
+--echo # ... server_1 -> server_2 is set up
+
+--connection server_1
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Innodb;
+INSERT INTO t1 VALUES (1);
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+
+--echo # Circular configuration server_2 -> server_1 initialiation ...
+--connection server_1
+--echo # A. ... first when server_1 is in gtid strict mode...
+set @@global.gtid_strict_mode = true;
+set @@global.rpl_semi_sync_slave_enabled = 1;
+
+evalp CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root', master_use_gtid=SLAVE_POS;
+
+--echo # ... only for it to fail 'cos if its inconsistent (empty) slave's gtid state:
+SELECT @@global.gtid_slave_pos;
+START SLAVE;
+# ER_GTID_STRICT_OUT_OF_ORDER
+--let $slave_sql_errno = 1950
+--source include/wait_for_slave_sql_error.inc
+
+--echo # B. ... Resume on the circular setup with the server_id now in the non-strict mode ...
+set @@global.gtid_strict_mode = false;
+--source include/start_slave.inc
+
+--echo # ... to have succeeded.
+
+--connection server_2
+INSERT INTO t1 VALUES (2);
+--save_master_pos
+
+--connection server_1
+--sync_with_master
+
+INSERT INTO t1 VALUES (3);
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+--echo # The gtid states on server_2 must be equal to ...
+--let $wait_condition=select @@gtid_slave_pos=@@gtid_binlog_pos
+--source include/wait_condition.inc
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+
+--connection server_1
+--echo # ... the gtid states on server_1
+--let $wait_condition=select @@gtid_slave_pos=@@gtid_binlog_pos
+--source include/wait_condition.inc
+SHOW VARIABLES LIKE 'gtid_slave_pos';
+SHOW VARIABLES LIKE 'gtid_binlog_pos';
+
+--echo # Cleanup
+--connection server_1
+--source include/stop_slave.inc
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+set @@global.rpl_semi_sync_master_wait_point=default;
+
+DROP TABLE t1;
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+set @@global.rpl_semi_sync_master_enabled = default;
+set @@global.rpl_semi_sync_slave_enabled = default;
+
+--source include/rpl_end.inc
diff --git a/sql/slave.cc b/sql/slave.cc
index c0eef02ca7a..a6578be199a 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -6186,13 +6186,13 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
bool is_rows_event= false;
/*
The flag has replicate_same_server_id semantics and is raised to accept
- a same-server-id event on the semisync slave, for both the gtid and legacy
- connection modes.
- Such events can appear as result of this server recovery so the event
- was created there and replicated elsewhere right before the crash. At recovery
- it could be evicted from the server's binlog.
- */
- bool do_accept_own_server_id= false;
+ a same-server-id event group by the gtid strict mode semisync slave.
+ Own server-id events can appear as result of this server crash-recovery:
+ the transaction was created on this server then being master, got replicated
+ elsewhere right before the crash before commit;
+ finally at recovery the transaction gets evicted from the server's binlog.
+ */
+ bool do_accept_own_server_id;
/*
FD_q must have been prepared for the first R_a event
inside get_master_version_and_clock()
@@ -6281,6 +6281,8 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
dbug_rows_event_count = 0;
};);
#endif
+ s_id= uint4korr(buf + SERVER_ID_OFFSET);
+
mysql_mutex_lock(&mi->data_lock);
switch (buf[EVENT_TYPE_OFFSET]) {
@@ -6722,6 +6724,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
++mi->events_queued_since_last_gtid;
inc_pos= event_len;
+
}
break;
/*
@@ -6864,6 +6867,10 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
break;
}
+ do_accept_own_server_id= (s_id == global_system_variables.server_id
+ && rpl_semi_sync_slave_enabled && opt_gtid_strict_mode
+ && mi->using_gtid != Master_info::USE_GTID_NO);
+
/*
Integrity of Rows- event group check.
A sequence of Rows- events must end with STMT_END_F flagged one.
@@ -6909,7 +6916,6 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
*/
mysql_mutex_lock(log_lock);
- s_id= uint4korr(buf + SERVER_ID_OFFSET);
/*
Write the event to the relay log, unless we reconnected in the middle
of an event group and now need to skip the initial part of the group that
@@ -6955,7 +6961,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
else
if ((s_id == global_system_variables.server_id &&
!(mi->rli.replicate_same_server_id ||
- (do_accept_own_server_id= rpl_semi_sync_slave_enabled))) ||
+ do_accept_own_server_id)) ||
event_that_should_be_ignored(buf) ||
/*
the following conjunction deals with IGNORE_SERVER_IDS, if set