From d5a7c9d76af911d7267d6a3b15e894246f6eaee2 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 4 Jan 2018 02:11:01 +0200 Subject: The slave io thread does not conduct integrity check for row-based events. Specifically it tolerates missed STMT_END flag marked terminal event that conclude a sequence of "elementary" "block" Rows-events. Failure to react on a potentially missed event can confuse the applier thread in various ways. The slave io is made in this patch to track the STMT_END status. Whenever at a first event following a sequence of Rows events the IO thread finds out that a preceding Rows event did not actually had the flag, an explicit error is issued. Replication can be resumed as a provided test demonstrates. Note that currently the row-based group integrity check is limited to the version 1 rows event which are generated by Mariadb masters. --- .../rpl/r/rpl_row_end_of_statement_loss.result | 22 +++++++++++++ .../rpl/t/rpl_row_end_of_statement_loss-master.opt | 2 ++ .../suite/rpl/t/rpl_row_end_of_statement_loss.test | 37 ++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result create mode 100644 mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test diff --git a/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result b/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result new file mode 100644 index 00000000000..096f45ebd30 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_end_of_statement_loss.result @@ -0,0 +1,22 @@ +include/master-slave.inc +[connection master] +connection slave; +call mtr.add_suppression("Slave IO thread did not receive an expected Rows-log-event marked as end-of-statement"); +call mtr.add_suppression("Relay log write failure: could not queue event from master"); +SET @save_debug= @@global.debug; +SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event"; +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, MASTER_USE_GTID=SLAVE_POS; +connection master; +CREATE TABLE t (a INT, b text(8192));; +INSERT INTO t values (1, repeat('b', 8192)), (1, repeat('b', 8192)); +connection slave; +START SLAVE IO_THREAD; +include/wait_for_slave_io_error.inc [errno=1595] +SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event"; +include/start_slave.inc +connection master; +DROP TABLE t; +connection slave; +SET GLOBAL debug_dbug= @save_debug; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt new file mode 100644 index 00000000000..144bbca0730 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt @@ -0,0 +1,2 @@ +--binlog-row-event-max-size=8192 + diff --git a/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test new file mode 100644 index 00000000000..d91dd610de6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test @@ -0,0 +1,37 @@ +--source include/have_debug.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +# Loss of STMT_END flagged event must error out the IO thread +--connection slave +call mtr.add_suppression("Slave IO thread did not receive an expected Rows-log-event marked as end-of-statement"); +call mtr.add_suppression("Relay log write failure: could not queue event from master"); + +SET @save_debug= @@global.debug; +SET GLOBAL debug_dbug="+d,simulate_stmt_end_rows_event"; +--source include/stop_slave.inc +--replace_result $MASTER_MYPORT MASTER_PORT +--eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, MASTER_USE_GTID=SLAVE_POS + +--connection master +--let $max_row_size=8192 +--eval CREATE TABLE t (a INT, b text($max_row_size)); +--eval INSERT INTO t values (1, repeat('b', $max_row_size)), (1, repeat('b', $max_row_size)) + +# Prove that the missed STMT_END marked rows-event +# causes the io thread stop. +--connection slave +START SLAVE IO_THREAD; +--let $slave_io_errno=1595 +--source include/wait_for_slave_io_error.inc +SET GLOBAL debug_dbug="-d,simulate_stmt_end_rows_event"; +--source include/start_slave.inc + +# cleanup + +--connection master +DROP TABLE t; +sync_slave_with_master; +SET GLOBAL debug_dbug= @save_debug; + +--source include/rpl_end.inc -- cgit v1.2.1