Skip to content

Commit

Permalink
MDEV-14721 Big transaction events get lost on semisync master when
Browse files Browse the repository at this point in the history
           replicate_events_marked_for_skip=FILTER_ON_MASTER

When events of a big transaction are binlogged offsetting over 2GB from
the beginning of the log the semisync master's dump thread
lost such events.
The events were skipped by the Dump thread that found their skipping
status erroneously.

The current fixes make sure the skipping status is computed correctly.
The test verifies them simulating the 2GB offset.
  • Loading branch information
andrelkin authored and montywi committed Jan 27, 2018
1 parent 0d31b4b commit c09371d
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 5 deletions.
30 changes: 30 additions & 0 deletions mysql-test/suite/rpl/r/rpl_semi_sync_skip_repl.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
include/master-slave.inc
[connection master]
connection master;
call mtr.add_suppression("Timeout waiting for reply of binlog");
SET @@GLOBAL.rpl_semi_sync_master_enabled = 1;
SET @@GLOBAL.rpl_semi_sync_master_timeout=100;
connection slave;
include/stop_slave.inc
SET @@GLOBAL.replicate_events_marked_for_skip=FILTER_ON_MASTER;
SET @@GLOBAL. rpl_semi_sync_slave_enabled = 1;
include/start_slave.inc
connection master;
CREATE TABLE t1 (a INT) ENGINE=innodb;
SET @@GLOBAL.debug_dbug= "d,dbug_master_binlog_over_2GB";
SET @@SESSION.skip_replication=1;
INSERT INTO t1 SET a=1;
SET @@SESSION.skip_replication=0;
INSERT INTO t1 SET a=0;
connection slave;
connection master;
SET @@GLOBAL.debug_dbug="";
SET @@GLOBAL. rpl_semi_sync_master_timeout = 10000;
SET @@GLOBAL. rpl_semi_sync_master_enabled = 0;
connection master;
DROP TABLE t1;
connection slave;
include/stop_slave.inc
SET @@GLOBAL. rpl_semi_sync_slave_enabled = 0;
SET @@GLOBAL.replicate_events_marked_for_skip = REPLICATE;
include/rpl_end.inc
62 changes: 62 additions & 0 deletions mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# MDEV-14721 Big transaction events get lost on semisync master when
# replicate_events_marked_for_skip=FILTER_ON_MASTER
#
# When events of a big transaction are binlogged offsetting over 2GB from
# the beginning of the log the semisync master's dump thread
# lost such events.
# The test verifies the fixes' correctness simulating the 2GB offset.

source include/have_semisync.inc;
source include/not_embedded.inc;
source include/have_innodb.inc;
source include/have_debug.inc;
source include/master-slave.inc;

--connection master
# Suppress warnings that might be generated during the test
call mtr.add_suppression("Timeout waiting for reply of binlog");

--let $sav_enabled_master=`SELECT @@GLOBAL.rpl_semi_sync_master_enabled `
--let $sav_timeout_master=`SELECT @@GLOBAL.rpl_semi_sync_master_timeout `
SET @@GLOBAL.rpl_semi_sync_master_enabled = 1;
SET @@GLOBAL.rpl_semi_sync_master_timeout=100;

--connection slave
source include/stop_slave.inc;
--let $sav_skip_marked_slave=`SELECT @@GLOBAL.replicate_events_marked_for_skip `
SET @@GLOBAL.replicate_events_marked_for_skip=FILTER_ON_MASTER;
--let $sav_enabled_slave=`SELECT @@GLOBAL.rpl_semi_sync_slave_enabled `
SET @@GLOBAL. rpl_semi_sync_slave_enabled = 1;

source include/start_slave.inc;

--connection master
CREATE TABLE t1 (a INT) ENGINE=innodb;

# Make the following events as if they offset over 2GB from the beginning of binlog
SET @@GLOBAL.debug_dbug= "d,dbug_master_binlog_over_2GB";
SET @@SESSION.skip_replication=1;
INSERT INTO t1 SET a=1;
SET @@SESSION.skip_replication=0;
INSERT INTO t1 SET a=0;

--sync_slave_with_master

#
# Clean up
#
--connection master
SET @@GLOBAL.debug_dbug="";
--eval SET @@GLOBAL. rpl_semi_sync_master_timeout = $sav_timeout_master
--eval SET @@GLOBAL. rpl_semi_sync_master_enabled = $sav_enabled_master

--connection master
DROP TABLE t1;

--sync_slave_with_master
source include/stop_slave.inc;
--eval SET @@GLOBAL. rpl_semi_sync_slave_enabled = $sav_enabled_slave
--eval SET @@GLOBAL.replicate_events_marked_for_skip = $sav_skip_marked_slave

--let $rpl_only_running_threads= 1
--source include/rpl_end.inc
2 changes: 2 additions & 0 deletions sql/log_event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,8 @@ bool Log_event::write_header(ulong event_data_length)
*/

log_pos= writer->pos() + data_written;

DBUG_EXECUTE_IF("dbug_master_binlog_over_2GB", log_pos += (1ULL <<31););
}

now= get_time(); // Query start time
Expand Down
7 changes: 2 additions & 5 deletions sql/sql_repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1904,11 +1904,8 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type,
*/
if (info->thd->variables.option_bits & OPTION_SKIP_REPLICATION)
{
/*
The first byte of the packet is a '\0' to distinguish it from an error
packet. So the actual event starts at offset +1.
*/
uint16 event_flags= uint2korr(&((*packet)[FLAGS_OFFSET+1]));
uint16 event_flags= uint2korr(&((*packet)[FLAGS_OFFSET + ev_offset]));

if (event_flags & LOG_EVENT_SKIP_REPLICATION_F)
return NULL;
}
Expand Down

0 comments on commit c09371d

Please sign in to comment.