1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-15393 gtid_slave_pos duplicate key errors after mysqldump restore

When mysqldump is run to dump the `mysql` system database, it generates
INSERT statements into the table `mysql.gtid_slave_pos`.
After running the backup script
those inserts did not produce the expected gtid state on slave. In
particular the maximum of mysql.gtid_slave_pos.sub_id did not make
into
   rpl_global_gtid_slave_state.last_sub_id

an in-memory object that is supposed to match the current state of the
table. And that was regardless of whether --gtid option was specified
or not. Later when the backup recipient server starts as slave
in *non-gtid* mode this desychronization may lead to a duplicate key
error.

This effect is corrected for --gtid mode mysqldump/mariadb-dump only
as the following.  The fixes ensure the insert block of the dump
script is followed with a "summing-up" SET @global.gtid_slave_pos
assignment.

For the implemenation part, note a deferred print-out of
SET-gtid_slave_pos and associated comments is prefered over relocating
of the entire blocks if (opt_master,slave_data &&
do_show_master,slave_status) ...  because of compatiblity
concern. Namely an error inside do_show_*() is handled in the new code
the same way, as early as, as before.

A regression test can be run in how-to-reproduce mode as well.
One affected mtr test observed.
rpl_mysqldump_slave.result "mismatch" shows now the new deferring print
of SET-gtid_slave_pos policy in action.
This commit is contained in:
Andrei
2024-07-15 17:50:37 +03:00
parent b8b6cab2d7
commit b8f92ade57
4 changed files with 396 additions and 41 deletions

View File

@ -8,26 +8,25 @@ connection master;
use test;
connection slave;
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='';
CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='';
/*M!999999\- enable the sandbox mode */
STOP ALL SLAVES;
-- SET GLOBAL gtid_slave_pos='';
CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='';
START ALL SLAVES;
/*M!999999\- enable the sandbox mode */
STOP ALL SLAVES;
-- SET GLOBAL gtid_slave_pos='';
CHANGE MASTER '' TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_MYPORT, MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='';
START ALL SLAVES;
start slave;
Warnings:
Note 1254 Slave is already running
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='';
CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
start slave;
@ -46,72 +45,72 @@ DROP TABLE t2;
1. --dump-slave=1 --gtid
/*M!999999\- enable the sandbox mode */
SET GLOBAL gtid_slave_pos='0-1-1001';
CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos;
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
SET GLOBAL gtid_slave_pos='0-1-1001';
1a. --dump-slave=1
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='0-1-1001';
CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='0-1-1001';
2. --dump-slave=2 --gtid
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='0-1-1001';
-- CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos;
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='0-1-1001';
2. --dump-slave=2
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='0-1-1001';
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='0-1-1001';
*** Test mysqldump --master-data GTID/non-gtid functionality.
1. --master-data=1 --gtid
/*M!999999\- enable the sandbox mode */
CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
SET GLOBAL gtid_slave_pos='0-2-1003';
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
SET GLOBAL gtid_slave_pos='0-2-1003';
1a. --master-data=1
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='0-2-1003';
CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='0-2-1003';
2. --master-data=2 --gtid
/*M!999999\- enable the sandbox mode */
-- CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
-- SET GLOBAL gtid_slave_pos='0-2-1003';
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='0-2-1003';
2a. --master-data=2
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='0-2-1003';
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='0-2-1003';
3. --master-data --single-transaction --gtid
/*M!999999\- enable the sandbox mode */
CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
SET GLOBAL gtid_slave_pos='0-2-1003';
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
SET GLOBAL gtid_slave_pos='0-2-1003';
3a. --master-data --single-transaction
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='0-2-1003';
CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='0-2-1003';
4. --master-data=2 --dump-slave=2 --single-transaction --gtid (MDEV-4827)
@ -130,11 +129,9 @@ CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-- Preferably use GTID to start replication from GTID position:
-- CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
-- SET GLOBAL gtid_slave_pos='0-2-1003';
-- A corresponding to the above master-data CHANGE-MASTER settings to the slave gtid state is printed later in the file.
--
-- Alternately, following is the position of the binary logging from SHOW MASTER STATUS at point of backup.
@ -149,14 +146,24 @@ CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START
-- Use this position when creating a clone of, or replacement server, from where the backup was taken.
-- This new server will connects to the same primary server(s).
--
-- GTID position to start replication:
-- SET GLOBAL gtid_slave_pos='0-1-1001';
-- A corresponding to the below dump-slave CHANGE-MASTER settings to the slave gtid state is printed later in the file.
-- Use only the MASTER_USE_GTID=slave_pos or MASTER_LOG_FILE/MASTER_LOG_POS in the statements below.
-- CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos;
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- The deferred gtid setting for slave corresponding to the master-data CHANGE-MASTER follows
-- Preferably use GTID to start replication from GTID position:
-- SET GLOBAL gtid_slave_pos='0-2-1003';
-- The deferred gtid setting for slave corresponding to the dump-slave CHANGE-MASTER follows
-- GTID position to start replication:
-- SET GLOBAL gtid_slave_pos='0-1-1001';
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@ -187,10 +194,6 @@ CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-- Preferably use GTID to start replication from GTID position:
-- SET GLOBAL gtid_slave_pos='0-2-1003';
--
-- Alternately, following is the position of the binary logging from SHOW MASTER STATUS at point of backup.
-- Use this when creating a replica of the primary server where the backup was made.
@ -199,15 +202,27 @@ CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- A corresponding to the above master-data CHANGE-MASTER settings to the slave gtid state is printed as comments later in the file.
--
-- The following is the SQL position of the replication taken from SHOW SLAVE STATUS at the time of backup.
-- Use this position when creating a clone of, or replacement server, from where the backup was taken.
-- This new server will connects to the same primary server(s).
--
-- GTID position to start replication:
-- SET GLOBAL gtid_slave_pos='0-1-1001';
-- A corresponding to the below dump-slave CHANGE-MASTER settings to the slave gtid state is printed later in the file.
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
-- The deferred gtid setting for slave corresponding to the master-data CHANGE-MASTER follows
-- Preferably use GTID to start replication from GTID position:
-- SET GLOBAL gtid_slave_pos='0-2-1003';
-- The deferred gtid setting for slave corresponding to the dump-slave CHANGE-MASTER follows
-- GTID position to start replication:
-- SET GLOBAL gtid_slave_pos='0-1-1001';
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@ -232,8 +247,8 @@ change master to master_use_gtid=slave_pos;
connection master;
# Ensuring the binlog dump thread is killed on primary...
/*M!999999\- enable the sandbox mode */
-- SET GLOBAL gtid_slave_pos='0-1-1005';
-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000002', MASTER_LOG_POS=BINLOG_START;
-- SET GLOBAL gtid_slave_pos='0-1-1005';
connection slave;
include/start_slave.inc
include/rpl_end.inc