Commit 7a80c534 authored by unknown's avatar unknown

MDEV-4645: Incorrect reads of frozen binlog events; FDE corrupted in relay log

  
  Currently several places use description_event->common_header_len instead of
  LOG_EVENT_MINIMAL_HEADER_LEN when parsing events with "frozen" headers (such
  as Start_event_v3 and its subclasses such as Format_description_log_event, as
  well as Rotate_event). This causes events with extra headers (which would otherwise
  be valid and those headers ignored) to be corrupted due to over-reading or skipping
  into the data portion of the log events.
  
  It is rewritten in some details patch of Jeremy Cole (See MDEV):
  - The virtual function returns length to avoid IFs (and only one call of the virtual function made)
  - Printing function avoids printing strings
parent ada15c7a
This diff is collapsed.
...@@ -275,17 +275,16 @@ FLUSH LOGS; ...@@ -275,17 +275,16 @@ FLUSH LOGS;
DROP TABLE t1; DROP TABLE t1;
# We create a table, patch, and load the output into it # We create a table named "patch", and load the output into it.
# By using LINES STARTING BY '#' + SELECT WHERE a LIKE 'Query' # By using LIKE, we can easily see if the output is missing the '#'
# We can easily see if a 'Query' line is missing the '#' character # character, as described in the bug.
# as described in the original bug
--disable_query_log --disable_query_log
CREATE TABLE patch (a BLOB); CREATE TABLE patch (a BLOB);
--exec $MYSQL_BINLOG --hexdump --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000012 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat --exec $MYSQL_BINLOG --hexdump --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000012 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat
### Starting master-bin.000014 ### Starting master-bin.000014
eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat' eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat'
INTO TABLE patch FIELDS TERMINATED BY '' LINES STARTING BY '#'; INTO TABLE patch FIELDS TERMINATED BY '';
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat --remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat
--enable_query_log --enable_query_log
...@@ -293,7 +292,7 @@ eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat' ...@@ -293,7 +292,7 @@ eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat'
--echo The bug being tested was that 'Query' lines were not preceded by '#' --echo The bug being tested was that 'Query' lines were not preceded by '#'
--echo If the line is in the table, it had to have been preceded by a '#' --echo If the line is in the table, it had to have been preceded by a '#'
--echo --echo
SELECT COUNT(*) AS `BUG#28293_expect_2` FROM patch WHERE a LIKE '%Query%'; SELECT COUNT(*) AS `BUG#28293_expect_2` FROM patch WHERE a LIKE '#%Query%';
DROP TABLE patch; DROP TABLE patch;
# #
...@@ -594,3 +593,12 @@ SHOW TABLES IN test; ...@@ -594,3 +593,12 @@ SHOW TABLES IN test;
--exec $MYSQL_BINLOG --server-id=2 $MYSQLD_DATADIR/$master_binlog | $MYSQL --exec $MYSQL_BINLOG --server-id=2 $MYSQLD_DATADIR/$master_binlog | $MYSQL
SHOW TABLES IN test; SHOW TABLES IN test;
eval SET GLOBAL SERVER_ID = $old_server_id; eval SET GLOBAL SERVER_ID = $old_server_id;
--echo #
--echo # MDEV-4645: Incorrect reads of frozen binlog events;
--echo # FDE corrupted in relay log
--echo #
--exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_checksum.binlog
--exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_group_id.binlog
--exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_group_id_checksum.binlog
--exec $MYSQL_BINLOG --hexdump std_data/mdev-4645-binlog_none.binlog
This diff is collapsed.
...@@ -1253,6 +1253,7 @@ class Log_event ...@@ -1253,6 +1253,7 @@ class Log_event
#endif #endif
virtual Log_event_type get_type_code() = 0; virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0; virtual bool is_valid() const = 0;
virtual my_off_t get_header_len(my_off_t len) { return len; }
void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; } void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; }
void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; } void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; }
bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; } bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
...@@ -2469,6 +2470,8 @@ class Start_log_event_v3: public Log_event ...@@ -2469,6 +2470,8 @@ class Start_log_event_v3: public Log_event
const Format_description_log_event* description_event); const Format_description_log_event* description_event);
~Start_log_event_v3() {} ~Start_log_event_v3() {}
Log_event_type get_type_code() { return START_EVENT_V3;} Log_event_type get_type_code() { return START_EVENT_V3;}
my_off_t get_header_len(my_off_t l __attribute__((unused)))
{ return LOG_EVENT_MINIMAL_HEADER_LEN; }
#ifdef MYSQL_SERVER #ifdef MYSQL_SERVER
bool write(IO_CACHE* file); bool write(IO_CACHE* file);
#endif #endif
...@@ -2984,6 +2987,8 @@ class Rotate_log_event: public Log_event ...@@ -2984,6 +2987,8 @@ class Rotate_log_event: public Log_event
my_free((void*) new_log_ident); my_free((void*) new_log_ident);
} }
Log_event_type get_type_code() { return ROTATE_EVENT;} Log_event_type get_type_code() { return ROTATE_EVENT;}
my_off_t get_header_len(my_off_t l __attribute__((unused)))
{ return LOG_EVENT_MINIMAL_HEADER_LEN; }
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;} int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
bool is_valid() const { return new_log_ident != 0; } bool is_valid() const { return new_log_ident != 0; }
#ifdef MYSQL_SERVER #ifdef MYSQL_SERVER
......
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