Skip to content

Commit

Permalink
MDEV-28609 refine gtid-strict-mode to ignore same server-id gtid from…
Browse files Browse the repository at this point in the history
… the past

... on semisync slave

To provide semisync master crash-recovery the same server-id transactions
were made to accept for execution on the semisync slave when the strict gtid
mode (see MDEV-27760).
That however caused out-of-order error on a master's transaction
server of the circular setup.
The error was fair in the sense of the gtid strict mode rule as indeed
under the condition of the circular setup the replicated transaction
already exists in the local binlog.

This is fixed by the commit to ignore on the gtid strict mode semisync
slave those gtids that exist in the slave's binlog that effectively restores
the default same-server-id ignore policy.
At the same time the fixes complies with MDEV-21117 semisync slave recovery
to accept the same server-id transactions that do not exist in local binlog.
  • Loading branch information
andrelkin committed Jul 26, 2022
1 parent 552919d commit 8d238d4
Show file tree
Hide file tree
Showing 14 changed files with 319 additions and 107 deletions.
4 changes: 3 additions & 1 deletion mysql-test/main/mysqld--help.result
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,9 @@ The following specify which files/extra groups are read (specified before remain
--gtid-strict-mode Enforce strict seq_no ordering of events in the binary
log. Slave stops with an error if it encounters an event
that would cause it to generate an out-of-order binlog if
executed.
executed. When ON the same server-id semisync-replicated
transactions that duplicate exising ones in binlog are
ignored without error and slave interruption.
-?, --help Display this help and exit.
--histogram-size=# Number of bytes used for a histogram. If set to 0, no
histograms are created by ANALYZE.
Expand Down
133 changes: 110 additions & 23 deletions mysql-test/suite/rpl/r/rpl_circular_semi_sync.result
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
include/master-slave.inc
[connection master]
# Master server_1 and Slave server_2 initialiation ...
# Master server_1 and Slave server_2 initialization ...
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;
Expand All @@ -22,31 +19,48 @@ 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
# server_1 -> server_2 semisync link is set up.
connection server_1;
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Innodb;
INSERT INTO t1 VALUES (1);
CREATE TABLE t1 (a INT PRIMARY KEY, b INT default 0) ENGINE=Innodb;
INSERT INTO t1(a) VALUES (1);
include/save_master_gtid.inc
connection server_2;
# Circular configuration server_2 -> server_1 initialiation ...
include/sync_with_master_gtid.inc
# Circular configuration server_1 -> server_2 -> server_1 ...
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.
... is done.
## A. no out-of-order gtid error for own transaction made round trip
connection server_2;
set @@global.gtid_strict_mode = true;
set @@global.rpl_semi_sync_master_enabled = 1;
INSERT INTO t1(a) VALUES (2);
include/save_master_gtid.inc
connection server_1;
#
# the successful sync is a required proof
#
include/sync_with_master_gtid.inc
update t1 set b=b+1 where a=2;
include/save_master_gtid.inc
connection server_2;
INSERT INTO t1 VALUES (2);
include/sync_with_master_gtid.inc
# Post-execution state check on both servers synchronized with each other
connection server_1;
INSERT INTO t1 VALUES (3);
# ... 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
SELECT * from t1;
a b
1 0
2 1
connection server_2;
# The gtid states on server_2 must be equal to ...
SHOW VARIABLES LIKE 'gtid_binlog_pos';
Expand All @@ -55,22 +69,95 @@ 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
SELECT * from t1;
a b
1 0
2 1
## B. out-of-order gtid error for a "foreign" server-id transaction
connection server_1;
set statement sql_log_bin=0 for call mtr.add_suppression("Slave: An attempt was made to binlog GTID 10-2-4");
set @@session.server_id=2;
INSERT INTO t1(a) VALUES (3);
set @@session.server_id=default;
include/save_master_gtid.inc
connection server_2;
include/sync_with_master_gtid.inc
INSERT INTO t1(a) VALUES (4);
include/save_master_gtid.inc
connection server_1;
include/wait_for_slave_sql_error.inc [errno=1950]
set sql_slave_skip_counter=1;
include/start_slave.inc
include/sync_with_master_gtid.inc
connection server_2;
set statement sql_log_bin=0 for call mtr.add_suppression("Slave: An attempt was made to binlog GTID 20-1-3");
set @@session.server_id=1;
INSERT INTO t1(a) VALUES (5);
set @@session.server_id=default;
include/save_master_gtid.inc
connection server_1;
include/sync_with_master_gtid.inc
INSERT INTO t1(a) VALUES (6);
include/save_master_gtid.inc
connection server_2;
include/wait_for_slave_sql_error.inc [errno=1950]
set sql_slave_skip_counter=1;
include/start_slave.inc
include/sync_with_master_gtid.inc
# Post-execution state check on both servers synchronized with each other
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
gtid_slave_pos 0-2-1,10-1-5,20-1-3
SHOW VARIABLES LIKE 'gtid_binlog_pos';
Variable_name Value
gtid_binlog_pos 0-2-1,10-1-3,20-2-1
gtid_binlog_pos 0-2-1,10-1-5,20-1-3
SELECT * from t1;
a b
1 0
2 1
3 0
4 0
5 0
6 0
connection server_2;
include/sync_with_master_gtid.inc
# 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-5,20-1-3
SHOW VARIABLES LIKE 'gtid_slave_pos';
Variable_name Value
gtid_slave_pos 0-2-1,10-1-5,20-1-3
SELECT * from t1;
a b
1 0
2 1
3 0
4 0
5 0
6 0
#
# Cleanup
#
connection server_1;
DROP TABLE t1;
include/save_master_gtid.inc
connection server_2;
include/sync_with_master_gtid.inc
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;
set @@global.gtid_ignore_duplicates = default;
set @@global.gtid_strict_mode = default;
connection server_2;
include/stop_slave.inc
set @@global.gtid_ignore_duplicates = default;
set @@global.rpl_semi_sync_master_enabled = default;
set @@global.rpl_semi_sync_slave_enabled = default;
set @@global.gtid_strict_mode = default;
include/start_slave.inc
include/rpl_end.inc
30 changes: 24 additions & 6 deletions mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ INSERT INTO t1 VALUES (3, 'dummy3');
SHOW VARIABLES LIKE 'gtid_binlog_pos';
Variable_name Value
gtid_binlog_pos 0-2-5
SHOW VARIABLES LIKE 'gtid_binlog_state';
Variable_name Value
gtid_binlog_state 0-1-4,0-2-5
SHOW VARIABLES LIKE 'gtid_slave_pos';
Variable_name Value
gtid_slave_pos 0-1-4
Expand All @@ -84,12 +87,15 @@ gtid_slave_pos 0-2-5
SHOW VARIABLES LIKE 'gtid_binlog_pos';
Variable_name Value
gtid_binlog_pos 0-2-5
SHOW VARIABLES LIKE 'gtid_binlog_state';
Variable_name Value
gtid_binlog_state 0-1-4,0-2-5
connection server_2;
#
# Case:2
#
# CRASH the new master, and FAILOVER back to the original
# INSERT INTO t1 VALUES (4, REPEAT("x", 4100))
# SET STATEMENT server_id=1 FOR INSERT INTO t1 VALUES (4, REPEAT("x", 4100))
# INSERT INTO t1 VALUES (5, REPEAT("x", 4100))
# Rows 4 and 5 will be in master's binlog but not committed, they get
# replicated to slave and applied. On crash master should have 3 rows
Expand All @@ -98,14 +104,14 @@ connection server_2;
# Expected State post crash:
#=================================================================
# Master | Slave |
# 0-2-6 (Not commited) | 0-2-6 (Received through semi-sync |
# 0-1-6 (Not commited) | 0-1-6 (Received through semi-sync |
# | replication and applied) |
# 0-2-7 (Not commited) | 0-2-7 (Received through semi-sync |
# | replication and applied) |
#=================================================================
connect conn_client,127.0.0.1,root,,test,$SERVER_MYPORT_2,;
SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL con1_ready WAIT_FOR con1_go";
INSERT INTO t1 VALUES (4, REPEAT("x", 4100));
SET STATEMENT server_id=1 FOR INSERT INTO t1 VALUES (4, REPEAT("x", 4100));
connect conn_client_2,127.0.0.1,root,,test,$SERVER_MYPORT_2,;
SET DEBUG_SYNC= "now WAIT_FOR con1_ready";
SET GLOBAL debug_dbug="d,Notify_binlog_EOF";
Expand All @@ -123,7 +129,7 @@ SELECT @@GLOBAL.gtid_current_pos;
# restart: --skip-slave-start=1 --rpl-semi-sync-slave-enabled=1
connection server_2;
include/assert.inc [Table t1 should have 3 rows.]
FOUND 1 /truncated binlog file:.*slave.*000002/ in mysqld.2.err
FOUND 1 /truncated binlog file:.*slave.*000002.* to remove transactions starting from GTID 0-1-6/ in mysqld.2.err
disconnect conn_client;
connection server_1;
set global rpl_semi_sync_master_enabled = 1;
Expand All @@ -134,14 +140,17 @@ set global rpl_semi_sync_slave_enabled = 1;
set @@global.gtid_slave_pos=@@global.gtid_binlog_pos;
include/start_slave.inc
#
# Server_1 promoted as master will send 0-2-6 and 0-2-7 to slave Server_2
# Server_1 promoted as master will send 0-1-6 and 0-2-7 to slave Server_2
#
connection server_1;
INSERT INTO t1 VALUES (6, 'dummy6');
# The gtid state on current master must be equal to ...
SHOW VARIABLES LIKE 'gtid_binlog_pos';
Variable_name Value
gtid_binlog_pos 0-1-8
SHOW VARIABLES LIKE 'gtid_binlog_state';
Variable_name Value
gtid_binlog_state 0-2-7,0-1-8
SHOW VARIABLES LIKE 'gtid_slave_pos';
Variable_name Value
gtid_slave_pos 0-2-7
Expand All @@ -156,6 +165,9 @@ gtid_slave_pos 0-1-8
SHOW VARIABLES LIKE 'gtid_binlog_pos';
Variable_name Value
gtid_binlog_pos 0-1-8
SHOW VARIABLES LIKE 'gtid_binlog_state';
Variable_name Value
gtid_binlog_state 0-2-7,0-1-8
include/diff_tables.inc [server_1:t1, server_2:t1]
connection server_1;
#
Expand Down Expand Up @@ -196,7 +208,7 @@ SELECT @@GLOBAL.gtid_current_pos;
# restart: --skip-slave-start=1 --rpl-semi-sync-slave-enabled=1
connection server_1;
include/assert.inc [Table t1 should have 6 rows.]
NOT FOUND /truncated binlog file:.*master.*000003/ in mysqld.1.err
FOUND 1 /truncated binlog file:.*master.*000002.* to remove transactions starting from GTID 0-1-9/ in mysqld.1.err
disconnect conn_client;
connection server_2;
set global rpl_semi_sync_master_enabled = 1;
Expand All @@ -216,6 +228,9 @@ include/save_master_gtid.inc
SHOW VARIABLES LIKE 'gtid_binlog_pos';
Variable_name Value
gtid_binlog_pos 0-2-10
SHOW VARIABLES LIKE 'gtid_binlog_state';
Variable_name Value
gtid_binlog_state 0-1-9,0-2-10
SHOW VARIABLES LIKE 'gtid_slave_pos';
Variable_name Value
gtid_slave_pos 0-1-9
Expand All @@ -231,6 +246,9 @@ gtid_slave_pos 0-2-10
SHOW VARIABLES LIKE 'gtid_binlog_pos';
Variable_name Value
gtid_binlog_pos 0-2-10
SHOW VARIABLES LIKE 'gtid_binlog_state';
Variable_name Value
gtid_binlog_state 0-1-9,0-2-10
#
# Cleanup
#
Expand Down
Loading

0 comments on commit 8d238d4

Please sign in to comment.