mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +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:
@ -5985,8 +5985,11 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
|
||||
} /* dump_selected_tables */
|
||||
|
||||
|
||||
const char fmt_gtid_pos[]= "%sSET GLOBAL gtid_slave_pos='%s';\n";
|
||||
|
||||
static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos,
|
||||
int have_mariadb_gtid, int use_gtid)
|
||||
int have_mariadb_gtid, int use_gtid,
|
||||
char *set_gtid_pos)
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *UNINIT_VAR(master);
|
||||
@ -6047,15 +6050,21 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos,
|
||||
/* gtid */
|
||||
if (have_mariadb_gtid)
|
||||
{
|
||||
print_comment(md_result_file, 0,
|
||||
"\n-- Preferably use GTID to start replication from GTID "
|
||||
"position:\n\n");
|
||||
if (use_gtid)
|
||||
{
|
||||
fprintf(md_result_file,
|
||||
"%sCHANGE MASTER TO MASTER_USE_GTID=slave_pos;\n",
|
||||
comment_prefix);
|
||||
fprintf(md_result_file,
|
||||
"%sSET GLOBAL gtid_slave_pos='%s';\n",
|
||||
/*
|
||||
When --gtid is specified defer print of SET gtid_slave_pos until
|
||||
after its placeholder table is guaranteed to have been dumped.
|
||||
*/
|
||||
print_comment(md_result_file, 0,
|
||||
"\n-- A corresponding to the above master-data "
|
||||
"CHANGE-MASTER settings to the slave gtid state is printed "
|
||||
"later in the file.\n");
|
||||
}
|
||||
sprintf(set_gtid_pos, fmt_gtid_pos,
|
||||
(!use_gtid ? "-- " : comment_prefix), gtid_pos);
|
||||
}
|
||||
|
||||
@ -6071,6 +6080,11 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos,
|
||||
fprintf(md_result_file,
|
||||
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
|
||||
(use_gtid ? "-- " : comment_prefix), file, offset);
|
||||
if (have_mariadb_gtid && !use_gtid)
|
||||
print_comment(md_result_file, 0,
|
||||
"\n-- A corresponding to the above master-data CHANGE-MASTER "
|
||||
"settings to the slave gtid state is printed as comments "
|
||||
"later in the file.\n");
|
||||
check_io(md_result_file);
|
||||
|
||||
if (!consistent_binlog_pos)
|
||||
@ -6140,8 +6154,8 @@ static int add_slave_statements(void)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int do_show_slave_status(MYSQL *mysql_con, int use_gtid,
|
||||
int have_mariadb_gtid)
|
||||
static int do_show_slave_status(MYSQL *mysql_con, int have_mariadb_gtid,
|
||||
int use_gtid, char* set_gtid_pos)
|
||||
{
|
||||
MYSQL_RES *UNINIT_VAR(slave);
|
||||
MYSQL_ROW row;
|
||||
@ -6181,10 +6195,12 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid,
|
||||
mysql_free_result(slave);
|
||||
return 1;
|
||||
}
|
||||
/* defer print similarly to do_show_master_status */
|
||||
print_comment(md_result_file, 0,
|
||||
"-- GTID position to start replication:\n");
|
||||
fprintf(md_result_file, "%sSET GLOBAL gtid_slave_pos='%s';\n",
|
||||
gtid_comment_prefix, gtid_pos);
|
||||
"\n-- A corresponding to the below dump-slave "
|
||||
"CHANGE-MASTER settings to the slave gtid state is printed "
|
||||
"later in the file.\n");
|
||||
sprintf(set_gtid_pos, fmt_gtid_pos, gtid_comment_prefix, gtid_pos);
|
||||
}
|
||||
if (use_gtid)
|
||||
print_comment(md_result_file, 0,
|
||||
@ -6905,6 +6921,34 @@ static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size)
|
||||
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
|
||||
}
|
||||
|
||||
/**
|
||||
Print earlier prepared SET @@global.gtid_slave_pos.
|
||||
|
||||
@param set_gtid_pos[in] formatted sql set statement
|
||||
**/
|
||||
static void do_print_set_gtid_slave_pos(const char *set_gtid_pos,
|
||||
my_bool is_master_data)
|
||||
{
|
||||
DBUG_ASSERT(opt_master_data || opt_slave_data);
|
||||
if (is_master_data)
|
||||
{
|
||||
print_comment(md_result_file, 0,
|
||||
"\n-- The deferred gtid setting for slave corresponding to "
|
||||
"the master-data CHANGE-MASTER follows\n");
|
||||
print_comment(md_result_file, 0,
|
||||
"\n-- Preferably use GTID to start replication from GTID "
|
||||
"position:\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
print_comment(md_result_file, 0,
|
||||
"\n-- The deferred gtid setting for slave corresponding to "
|
||||
"the dump-slave CHANGE-MASTER follows\n");
|
||||
print_comment(md_result_file, 0,
|
||||
"-- GTID position to start replication:\n");
|
||||
}
|
||||
fprintf(md_result_file, "%s", set_gtid_pos);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -6913,6 +6957,12 @@ int main(int argc, char **argv)
|
||||
int exit_code;
|
||||
int consistent_binlog_pos= 0;
|
||||
int have_mariadb_gtid= 0;
|
||||
/*
|
||||
to hold SET @@global.gtid_slave_pos which is deferred to print
|
||||
until the function epilogue.
|
||||
*/
|
||||
char master_set_gtid_pos[3 + sizeof(fmt_gtid_pos) + MAX_GTID_LENGTH]= {0};
|
||||
char slave_set_gtid_pos[3 + sizeof(fmt_gtid_pos) + MAX_GTID_LENGTH]= {0};
|
||||
MY_INIT(argv[0]);
|
||||
|
||||
sf_leaking_memory=1; /* don't report memory leaks on early exits */
|
||||
@ -7016,10 +7066,12 @@ int main(int argc, char **argv)
|
||||
goto err;
|
||||
|
||||
if (opt_master_data && do_show_master_status(mysql, consistent_binlog_pos,
|
||||
have_mariadb_gtid, opt_use_gtid))
|
||||
have_mariadb_gtid,
|
||||
opt_use_gtid, master_set_gtid_pos))
|
||||
goto err;
|
||||
if (opt_slave_data && do_show_slave_status(mysql, opt_use_gtid,
|
||||
have_mariadb_gtid))
|
||||
if (opt_slave_data && do_show_slave_status(mysql,
|
||||
have_mariadb_gtid,
|
||||
opt_use_gtid, slave_set_gtid_pos))
|
||||
goto err;
|
||||
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
|
||||
goto err;
|
||||
@ -7087,6 +7139,11 @@ int main(int argc, char **argv)
|
||||
if (opt_system & OPT_SYSTEM_TIMEZONES)
|
||||
dump_all_timezones();
|
||||
|
||||
if (opt_master_data && master_set_gtid_pos[0])
|
||||
do_print_set_gtid_slave_pos(master_set_gtid_pos, TRUE);
|
||||
if (opt_slave_data && slave_set_gtid_pos[0])
|
||||
do_print_set_gtid_slave_pos(slave_set_gtid_pos, FALSE);
|
||||
|
||||
/* add 'START SLAVE' to end of dump */
|
||||
if (opt_slave_apply && add_slave_statements())
|
||||
goto err;
|
||||
|
@ -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
|
||||
|
148
mysql-test/suite/rpl/r/rpl_mysqldump_gtid_slave_pos.result
Normal file
148
mysql-test/suite/rpl/r/rpl_mysqldump_gtid_slave_pos.result
Normal file
@ -0,0 +1,148 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
# Initialize
|
||||
connection slave;
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
||||
# Setup data
|
||||
connection master;
|
||||
CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/sync_with_master_gtid.inc
|
||||
# 1. run some replication load that adds records to gtid_slave_pos table
|
||||
# 2. stop slave, remove loaded data (it will be replicated), delete from
|
||||
# gtid_slave_pos as the table is going to be restored
|
||||
# 3. take dump from slave (master has an empty gtid_slave_pos)
|
||||
# with --gtid and for the default value of both
|
||||
# --dump-slave and --master-data
|
||||
# and in loop for the two options do:
|
||||
# 4. reset the slave state to install some initial state
|
||||
# 5. restart slave server, restore the dump
|
||||
# 6. check the final state which must be equal to the dump's one
|
||||
# 7. start replication to see no error => Q.E.D.
|
||||
# unless the test runs on a buggy version in which case set to zero.
|
||||
# 1.
|
||||
include/stop_slave.inc
|
||||
delete from mysql.gtid_slave_pos;
|
||||
connection master;
|
||||
insert into t1 set a = 5;
|
||||
insert into t1 set a = 4;
|
||||
insert into t1 set a = 3;
|
||||
insert into t1 set a = 2;
|
||||
insert into t1 set a = 1;
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
select * from mysql.gtid_slave_pos;
|
||||
domain_id sub_id server_id seq_no
|
||||
0 2 1 1
|
||||
0 3 1 2
|
||||
0 4 1 3
|
||||
0 5 1 4
|
||||
0 6 1 5
|
||||
0 7 1 6
|
||||
select @@global.gtid_slave_pos as "after initial slave got in sync";
|
||||
after initial slave got in sync
|
||||
0-1-6
|
||||
# 2.
|
||||
include/stop_slave.inc
|
||||
# 3. A
|
||||
include/stop_slave.inc
|
||||
include/stop_slave.inc
|
||||
# 4.
|
||||
set statement sql_log_bin=0 for delete from mysql.gtid_slave_pos;
|
||||
insert into mysql.gtid_slave_pos values (99 + 2, 1, 1, 1);
|
||||
# 5.
|
||||
include/rpl_restart_server.inc [server_number=2]
|
||||
select * from mysql.gtid_slave_pos;
|
||||
domain_id sub_id server_id seq_no
|
||||
101 1 1 1
|
||||
select @@global.gtid_slave_pos as "before dump restore";
|
||||
before dump restore
|
||||
101-1-1
|
||||
# 6.
|
||||
select * from mysql.gtid_slave_pos;
|
||||
domain_id sub_id server_id seq_no
|
||||
0 2 1 6
|
||||
select @@global.gtid_slave_pos as "after dump restore";
|
||||
after dump restore
|
||||
0-1-6
|
||||
# 7.
|
||||
reset slave;
|
||||
select @@global.gtid_slave_pos;
|
||||
@@global.gtid_slave_pos
|
||||
0-1-6
|
||||
change master to master_use_gtid=no;
|
||||
connection master;
|
||||
insert into t1 select 1+max(a),2 from t1;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
select * from mysql.gtid_slave_pos;
|
||||
domain_id sub_id server_id seq_no
|
||||
0 2 1 6
|
||||
0 3 1 1
|
||||
0 4 1 2
|
||||
0 5 1 3
|
||||
0 6 1 4
|
||||
0 7 1 5
|
||||
0 8 1 6
|
||||
0 9 1 7
|
||||
select @@global.gtid_slave_pos as "after slave got in sync";
|
||||
after slave got in sync
|
||||
0-1-7
|
||||
include/stop_slave.inc
|
||||
# 4.
|
||||
set statement sql_log_bin=0 for delete from mysql.gtid_slave_pos;
|
||||
insert into mysql.gtid_slave_pos values (99 + 1, 1, 1, 1);
|
||||
# 5.
|
||||
include/rpl_restart_server.inc [server_number=2]
|
||||
select * from mysql.gtid_slave_pos;
|
||||
domain_id sub_id server_id seq_no
|
||||
100 1 1 1
|
||||
select @@global.gtid_slave_pos as "before dump restore";
|
||||
before dump restore
|
||||
100-1-1
|
||||
# 6.
|
||||
select * from mysql.gtid_slave_pos;
|
||||
domain_id sub_id server_id seq_no
|
||||
0 2 1 6
|
||||
select @@global.gtid_slave_pos as "after dump restore";
|
||||
after dump restore
|
||||
0-1-6
|
||||
# 7.
|
||||
reset slave;
|
||||
select @@global.gtid_slave_pos;
|
||||
@@global.gtid_slave_pos
|
||||
0-1-6
|
||||
change master to master_use_gtid=no;
|
||||
connection master;
|
||||
insert into t1 select 1+max(a),1 from t1;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
select * from mysql.gtid_slave_pos;
|
||||
domain_id sub_id server_id seq_no
|
||||
0 2 1 6
|
||||
0 3 1 1
|
||||
0 4 1 2
|
||||
0 5 1 3
|
||||
0 6 1 4
|
||||
0 7 1 5
|
||||
0 8 1 6
|
||||
0 9 1 7
|
||||
0 10 1 8
|
||||
select @@global.gtid_slave_pos as "after slave got in sync";
|
||||
after slave got in sync
|
||||
0-1-8
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/sync_with_master_gtid.inc
|
||||
include/rpl_end.inc
|
135
mysql-test/suite/rpl/t/rpl_mysqldump_gtid_slave_pos.test
Normal file
135
mysql-test/suite/rpl/t/rpl_mysqldump_gtid_slave_pos.test
Normal file
@ -0,0 +1,135 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
--echo # Initialize
|
||||
--connection slave
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
||||
|
||||
--echo # Setup data
|
||||
--connection master
|
||||
CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB;
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
# The following test proves fixes to
|
||||
# MDEV-15393 gtid_slave_pos duplicate key errors after mysqldump restore
|
||||
#
|
||||
--echo # 1. run some replication load that adds records to gtid_slave_pos table
|
||||
--echo # 2. stop slave, remove loaded data (it will be replicated), delete from
|
||||
--echo # gtid_slave_pos as the table is going to be restored
|
||||
--echo # 3. take dump from slave (master has an empty gtid_slave_pos)
|
||||
--echo # with --gtid and for the default value of both
|
||||
--echo # --dump-slave and --master-data
|
||||
--echo # and in loop for the two options do:
|
||||
--echo # 4. reset the slave state to install some initial state
|
||||
--echo # 5. restart slave server, restore the dump
|
||||
--echo # 6. check the final state which must be equal to the dump's one
|
||||
--echo # 7. start replication to see no error => Q.E.D.
|
||||
--echo # unless the test runs on a buggy version in which case set $FIXED to zero.
|
||||
|
||||
# set to ZERO when run with mysqldump of buggy version
|
||||
--let $FIXED= 1
|
||||
|
||||
--echo # 1.
|
||||
--source include/stop_slave.inc
|
||||
delete from mysql.gtid_slave_pos;
|
||||
|
||||
--connection master
|
||||
--let $trx_number = 5
|
||||
--let $i = $trx_number
|
||||
while ($i)
|
||||
{
|
||||
eval insert into t1 set a = $i;
|
||||
--dec $i
|
||||
}
|
||||
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
# Prior tests in a mtr batch could leave the min value of sub_id column with
|
||||
# arbtirary value. Therefore before dumping let's
|
||||
# adjust mysql.gtid_slave_pos to have sub_id growing deterministically.
|
||||
# The value of 2 is choosen.
|
||||
--disable_query_log
|
||||
set statement sql_log_bin = 0 for update mysql.gtid_slave_pos set sub_id = sub_id - (select min(sub_id) from mysql.gtid_slave_pos) + 2;
|
||||
--enable_query_log
|
||||
select * from mysql.gtid_slave_pos;
|
||||
select @@global.gtid_slave_pos as "after initial slave got in sync";
|
||||
|
||||
--echo # 2.
|
||||
--source include/stop_slave.inc
|
||||
|
||||
--echo # 3. A
|
||||
# Two dumps prepared to be restored in the following loop
|
||||
--exec $MYSQL_DUMP_SLAVE --dump-slave --gtid mysql gtid_slave_pos > $MYSQLTEST_VARDIR/tmp/dump_2.sql
|
||||
--source include/stop_slave.inc
|
||||
|
||||
--exec $MYSQL_DUMP_SLAVE --master-data --gtid mysql gtid_slave_pos > $MYSQLTEST_VARDIR/tmp/dump_1.sql
|
||||
|
||||
--let $i=2
|
||||
while ($i)
|
||||
{
|
||||
--disable_warnings
|
||||
--source include/stop_slave.inc
|
||||
--enable_warnings
|
||||
--echo # 4.
|
||||
set statement sql_log_bin=0 for delete from mysql.gtid_slave_pos;
|
||||
# setup a new gtid/sub_id state as complication for future backup restore.
|
||||
# After the restore the new state must be a union of the backup state
|
||||
# and this one.
|
||||
--eval insert into mysql.gtid_slave_pos values (99 + $i, 1, 1, 1)
|
||||
|
||||
--echo # 5.
|
||||
--let $rpl_server_number= 2
|
||||
--source include/rpl_restart_server.inc
|
||||
select * from mysql.gtid_slave_pos;
|
||||
select @@global.gtid_slave_pos as "before dump restore";
|
||||
--let $dump=dump_$i.sql
|
||||
--exec $MYSQL_SLAVE mysql -e "source $MYSQLTEST_VARDIR/tmp/$dump"
|
||||
|
||||
--echo # 6.
|
||||
select * from mysql.gtid_slave_pos;
|
||||
select @@global.gtid_slave_pos as "after dump restore";
|
||||
|
||||
--echo # 7.
|
||||
reset slave;
|
||||
select @@global.gtid_slave_pos;
|
||||
change master to master_use_gtid=no;
|
||||
|
||||
--connection master
|
||||
eval insert into t1 select 1+max(a),$i from t1;
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
if ($FIXED)
|
||||
{
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
}
|
||||
if (!$FIXED)
|
||||
{
|
||||
start slave;
|
||||
--let $slave_sql_errno= 1942
|
||||
--source include/wait_for_slave_sql_error.inc
|
||||
|
||||
--die
|
||||
}
|
||||
select * from mysql.gtid_slave_pos;
|
||||
select @@global.gtid_slave_pos as "after slave got in sync";
|
||||
|
||||
--dec $i
|
||||
}
|
||||
--echo #
|
||||
--echo # Cleanup
|
||||
--echo #
|
||||
--connection master
|
||||
DROP TABLE t1;
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
--remove_files_wildcard $MYSQLTEST_VARDIR/tmp dump_*.sql
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
--source include/rpl_end.inc
|
Reference in New Issue
Block a user