Commit 5aaf73fc authored by unknown's avatar unknown

MDEV-26: Global transaction ID.

Add tests crashing the slave in the middle of replication and checking that
replication picks-up again on restart in a crash-safe way.

Fix silly code that causes crash by inserting uninitialised data into a hash.
parent 9303ecd0
......@@ -56,5 +56,36 @@ a
1
2
3
*** Test crashing slave at various points and check that it recovers crash-safe. ***
include/stop_slave.inc
SET GLOBAL debug_dbug="+d,inject_crash_before_write_rpl_slave_state";
START SLAVE;
INSERT INTO t1 VALUES (4);
include/stop_slave.inc
SET GLOBAL debug_dbug="+d,crash_commit_before";
START SLAVE;
INSERT INTO t1 VALUES (5);
include/stop_slave.inc
SET GLOBAL debug_dbug="+d,crash_commit_after";
START SLAVE;
INSERT INTO t1 VALUES (6);
include/stop_slave.inc
SET GLOBAL debug_dbug="+d,inject_crash_before_flush_rli";
START SLAVE;
INSERT INTO t1 VALUES (7);
include/stop_slave.inc
SET GLOBAL debug_dbug="+d,inject_crash_after_flush_rli";
START SLAVE;
INSERT INTO t1 VALUES (8);
SELECT * FROM t1 ORDER BY a;
a
1
2
3
4
5
6
7
8
DROP TABLE t1;
include/rpl_end.inc
......@@ -124,6 +124,140 @@ SHOW BINLOG EVENTS IN 'master-bin.000004' LIMIT 1,1;
--sync_with_master
SELECT * FROM t1 ORDER BY a;
--echo *** Test crashing slave at various points and check that it recovers crash-safe. ***
# Crash the slave just before updating mysql.rpl_slave_state table.
--source include/stop_slave.inc
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
# We do not have to save @@GLOBAL.debug_dbug, it is reset when slave crashes.
SET GLOBAL debug_dbug="+d,inject_crash_before_write_rpl_slave_state";
START SLAVE;
--connection server_1
INSERT INTO t1 VALUES (4);
--connection server_2
--source include/wait_until_disconnected.inc
--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
restart: --skip-slave-start=0
EOF
--enable_reconnect
--source include/wait_until_connected_again.inc
--let $wait_condition= SELECT COUNT(*) = 4 FROM t1
--source include/wait_condition.inc
# Crash the slave just before committing.
--source include/stop_slave.inc
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
SET GLOBAL debug_dbug="+d,crash_commit_before";
START SLAVE;
--connection server_1
INSERT INTO t1 VALUES (5);
--connection server_2
--source include/wait_until_disconnected.inc
--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
restart: --skip-slave-start=0
EOF
--enable_reconnect
--source include/wait_until_connected_again.inc
--let $wait_condition= SELECT COUNT(*) = 5 FROM t1
--source include/wait_condition.inc
# Crash the slave just after committing.
--source include/stop_slave.inc
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
SET GLOBAL debug_dbug="+d,crash_commit_after";
START SLAVE;
--connection server_1
INSERT INTO t1 VALUES (6);
--connection server_2
--source include/wait_until_disconnected.inc
--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
restart: --skip-slave-start=0
EOF
--enable_reconnect
--source include/wait_until_connected_again.inc
--let $wait_condition= SELECT COUNT(*) = 6 FROM t1
--source include/wait_condition.inc
# Crash the slave just before updating relay-log.info
--source include/stop_slave.inc
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
SET GLOBAL debug_dbug="+d,inject_crash_before_flush_rli";
START SLAVE;
--connection server_1
INSERT INTO t1 VALUES (7);
--connection server_2
--source include/wait_until_disconnected.inc
--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
restart: --skip-slave-start=0
EOF
--enable_reconnect
--source include/wait_until_connected_again.inc
--let $wait_condition= SELECT COUNT(*) = 7 FROM t1
--source include/wait_condition.inc
# Crash the slave just after updating relay-log.info
--source include/stop_slave.inc
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
wait
EOF
SET GLOBAL debug_dbug="+d,inject_crash_after_flush_rli";
START SLAVE;
--connection server_1
INSERT INTO t1 VALUES (8);
--connection server_2
--source include/wait_until_disconnected.inc
--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
restart: --skip-slave-start=0
EOF
--enable_reconnect
--source include/wait_until_connected_again.inc
--let $wait_condition= SELECT COUNT(*) = 8 FROM t1
--source include/wait_condition.inc
# Check that everything was replicated correctly.
SELECT * FROM t1 ORDER BY a;
--connection server_1
DROP TABLE t1;
......
......@@ -329,6 +329,7 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
table->field[1]->store(sub_id, true);
table->field[2]->store((ulonglong)gtid->server_id, true);
table->field[3]->store(gtid->seq_no, true);
DBUG_EXECUTE_IF("inject_crash_before_write_rpl_slave_state", DBUG_SUICIDE(););
if ((err= table->file->ha_write_row(table->record[0])))
goto end;
......
......@@ -1246,7 +1246,9 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
DBA aware of the problem in the error log.
*/
}
DBUG_EXECUTE_IF("inject_crash_before_flush_rli", DBUG_SUICIDE(););
flush_relay_log_info(this);
DBUG_EXECUTE_IF("inject_crash_after_flush_rli", DBUG_SUICIDE(););
/*
Note that Rotate_log_event::do_apply_event() does not call this
function, so there is no chance that a fake rotate event resets
......@@ -1453,6 +1455,10 @@ rpl_load_gtid_slave_state(THD *thd)
entry= (struct local_element *)rec;
if (entry->sub_id >= sub_id)
continue;
entry->sub_id= sub_id;
DBUG_ASSERT(entry->gtid.domain_id == domain_id);
entry->gtid.server_id= server_id;
entry->gtid.seq_no= seq_no;
}
else
{
......@@ -1462,17 +1468,16 @@ rpl_load_gtid_slave_state(THD *thd)
err= 1;
goto end;
}
entry->sub_id= sub_id;
entry->gtid.domain_id= domain_id;
entry->gtid.server_id= server_id;
entry->gtid.seq_no= seq_no;
if ((err= my_hash_insert(&hash, (uchar *)entry)))
{
my_free(entry);
goto end;
}
}
entry->sub_id= sub_id;
entry->gtid.domain_id= domain_id;
entry->gtid.server_id= server_id;
entry->gtid.seq_no= seq_no;
}
rpl_global_gtid_slave_state.lock();
......
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