Commit ce326166 authored by Alfranio Correia's avatar Alfranio Correia

BUG#55675 rpl.rpl_log_pos fails sporadically with error binlog truncated in the middle

There are two calls to read_log_event() on master in mysql_binlog_send().
Each call reads 19 bytes in this test case and the error of the second
read_log_event() is reported to the slave.

The second read_log_event() starts from position 94 (75 + 19) to 113
(75 + 19 + 19). Usually, there are two events in the binary log:

    . 0   - 3   - Header
    . 4   - 105 - Format Descriptor Event
    . 106 - 304 - Query Event

and both reads fail because operations are reading from invalid positions
as expected.

However, mysql_binlog_send() does not use the same IO_CACHE that is used to
write into binary log (i.e. mysql_bin_log.log_file) for the hot binary log.
It opens the binary log file directly by calling open_binlog() and creates a
separated IO_CACHE. So there is a possibly that after a master has flushed
the binary log file, the content has been cached by the filesystem, and has
not updated the disk file. If this happens, then a slave will only see part
of the file, and thus the second read_log_event() will report event truncated
error.

To fix the problem, if the first read_log_event() has failed, we ensure that
the second one will try to read from the same position.
parent 3e57bb42
......@@ -11,7 +11,6 @@
##############################################################################
rpl_row_create_table : Bug#51574 Feb 27 2010 andrei failed different way than earlier with bug#45576
rpl_log_pos : BUG#55675 Sep 10 2010 27 2010 alfranio rpl.rpl_log_pos fails sporadically with error binlog truncated in the middle
rpl_get_master_version_and_clock : Bug#59178 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock
rpl_row_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out
rpl_stm_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out
......@@ -545,8 +545,10 @@ impossible position";
while (!net->error && net->vio != 0 && !thd->killed)
{
my_off_t prev_pos= pos;
while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
{
prev_pos= my_b_tell(&log);
#ifndef DBUG_OFF
if (max_binlog_dump_events && !left_events--)
{
......@@ -613,8 +615,13 @@ impossible position";
here we were reading binlog that was not closed properly (as a result
of a crash ?). treat any corruption as EOF
*/
if (binlog_can_be_corrupted && error != LOG_READ_MEM)
if (binlog_can_be_corrupted &&
error != LOG_READ_MEM && error != LOG_READ_EOF)
{
my_b_seek(&log, prev_pos);
error=LOG_READ_EOF;
}
/*
TODO: now that we are logging the offset, check to make sure
the recorded offset and the actual match.
......
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