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
......@@ -630,7 +630,7 @@ We expect this value to be 2 (one for the INSERT, one for COMMIT).
The bug being tested was that 'Query' lines were not preceded by '#'
If the line is in the table, it had to have been preceded by a '#'
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%';
BUG#28293_expect_2
2
DROP TABLE patch;
......@@ -914,3 +914,339 @@ t1
SHOW TABLES IN test;
Tables_in_test
SET GLOBAL SERVER_ID = 1;
#
# MDEV-4645: Incorrect reads of frozen binlog events;
# FDE corrupted in relay log
#
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#130807 23:29:20 server id 1 end_log_pos 106
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 4 |20 ae 02 52 |0f |01 00 00 00 |66 00 00 00 |6a 00 00 00 |00 01
#
# 17 04 00 35 2e 31 2e 36 33 2d 67 6f 6f 67 6c 65 2d |..5.1.63-google-|
# 27 64 65 62 75 67 2d 6c 6f 67 00 00 00 00 00 00 00 |debug-log.......|
# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
# 47 00 00 00 00 20 ae 02 52 17 38 0d 00 08 00 12 00 |.... ..R.8......|
# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........|
# 67 08 08 02 |...|
#
# Event: Start: binlog v 4, server v 5.1.63-google-debug-log created 130807 23:29:20 at startup
ROLLBACK/*!*/;
BINLOG '
IK4CUg8BAAAAZgAAAGoAAAAAAQQANS4xLjYzLWdvb2dsZS1kZWJ1Zy1sb2cAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAgrgJSFzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 106
#130807 23:29:24 server id 1 end_log_pos 207
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 6a |24 ae 02 52 |02 |01 00 00 00 |65 00 00 00 |cf 00 00 00 |00 00
#
# 81 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 91 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# a1 04 08 00 08 00 08 00 00 63 72 65 61 74 65 20 74 |........create t|
# b1 61 62 6c 65 20 74 65 73 74 2e 74 31 20 28 69 64 |able test.t1 (id|
# c1 20 69 6e 74 20 6e 6f 74 20 6e 75 6c 6c 29 | int not null)|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375907364/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table test.t1 (id int not null)
/*!*/;
# at 207
#130807 23:29:26 server id 1 end_log_pos 305
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# cf |26 ae 02 52 |02 |01 00 00 00 |62 00 00 00 |31 01 00 00 |00 00
#
# e6 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# f6 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# 106 04 08 00 08 00 08 00 00 69 6e 73 65 72 74 20 69 |........insert i|
# 116 6e 74 6f 20 74 65 73 74 2e 74 31 20 28 69 64 29 |nto test.t1 (id)|
# 126 20 76 61 6c 75 65 73 20 28 31 29 | values (1)|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375907366/*!*/;
insert into test.t1 (id) values (1)
/*!*/;
# at 305
#130807 23:29:28 server id 1 end_log_pos 386
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 131 |28 ae 02 52 |02 |01 00 00 00 |51 00 00 00 |82 01 00 00 |00 00
#
# 148 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 158 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# 168 04 08 00 08 00 08 00 00 64 72 6f 70 20 74 61 62 |........drop tab|
# 178 6c 65 20 74 65 73 74 2e 74 31 |le test.t1|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375907368/*!*/;
drop table test.t1
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#130807 23:25:35 server id 1 end_log_pos 106
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 4 |3f ad 02 52 |0f |01 00 00 00 |66 00 00 00 |6a 00 00 00 |00 00
#
# 17 04 00 35 2e 31 2e 36 33 2d 67 6f 6f 67 6c 65 2d |..5.1.63-google-|
# 27 64 65 62 75 67 2d 6c 6f 67 00 00 00 00 00 00 00 |debug-log.......|
# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
# 47 00 00 00 00 3f ad 02 52 1b 38 0d 00 08 00 12 00 |....?..R.8......|
# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........|
# 67 08 08 02 |...|
#
# Event: Start: binlog v 4, server v 5.1.63-google-debug-log created 130807 23:25:35 at startup
ROLLBACK/*!*/;
BINLOG '
P60CUg8BAAAAZgAAAGoAAAAAAAQANS4xLjYzLWdvb2dsZS1kZWJ1Zy1sb2cAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAA/rQJSGzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 106
#130807 23:25:41 server id 1 end_log_pos 211
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 6a |45 ad 02 52 |02 |01 00 00 00 |69 00 00 00 |d3 00 00 00 |00 00
#
# 85 01 00 00 00 01 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 95 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# a5 04 08 00 08 00 08 00 00 63 72 65 61 74 65 20 74 |........create t|
# b5 61 62 6c 65 20 74 65 73 74 2e 74 31 20 28 69 64 |able test.t1 (id|
# c5 20 69 6e 74 20 6e 6f 74 20 6e 75 6c 6c 29 | int not null)|
#
# Event: Query thread_id=1 exec_time=1 error_code=0
SET TIMESTAMP=1375907141/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table test.t1 (id int not null)
/*!*/;
# at 211
#130807 23:25:44 server id 1 end_log_pos 313
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# d3 |48 ad 02 52 |02 |01 00 00 00 |66 00 00 00 |39 01 00 00 |00 00
#
# ee 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# fe 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# 10e 04 08 00 08 00 08 00 00 69 6e 73 65 72 74 20 69 |........insert i|
# 11e 6e 74 6f 20 74 65 73 74 2e 74 31 20 28 69 64 29 |nto test.t1 (id)|
# 12e 20 76 61 6c 75 65 73 20 28 31 29 | values (1)|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375907144/*!*/;
insert into test.t1 (id) values (1)
/*!*/;
# at 313
#130807 23:25:48 server id 1 end_log_pos 398
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 139 |4c ad 02 52 |02 |01 00 00 00 |55 00 00 00 |8e 01 00 00 |00 00
#
# 154 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 164 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# 174 04 08 00 08 00 08 00 00 64 72 6f 70 20 74 61 62 |........drop tab|
# 184 6c 65 20 74 65 73 74 2e 74 31 |le test.t1|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375907148/*!*/;
drop table test.t1
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#130807 23:20:55 server id 1 end_log_pos 106
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 4 |27 ac 02 52 |0f |01 00 00 00 |66 00 00 00 |6a 00 00 00 |00 01
#
# 17 04 00 35 2e 31 2e 36 33 2d 67 6f 6f 67 6c 65 2d |..5.1.63-google-|
# 27 64 65 62 75 67 2d 6c 6f 67 00 00 00 00 00 00 00 |debug-log.......|
# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
# 47 00 00 00 00 27 ac 02 52 1f 38 0d 00 08 00 12 00 |....'..R.8......|
# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........|
# 67 08 08 02 |...|
#
# Event: Start: binlog v 4, server v 5.1.63-google-debug-log created 130807 23:20:55 at startup
ROLLBACK/*!*/;
BINLOG '
J6wCUg8BAAAAZgAAAGoAAAAAAQQANS4xLjYzLWdvb2dsZS1kZWJ1Zy1sb2cAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAnrAJSHzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 106
#130807 23:21:19 server id 1 end_log_pos 215
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 6a |3f ac 02 52 |02 |01 00 00 00 |6d 00 00 00 |d7 00 00 00 |00 00
#
# 89 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 99 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# a9 04 08 00 08 00 08 00 00 63 72 65 61 74 65 20 74 |........create t|
# b9 61 62 6c 65 20 74 65 73 74 2e 74 31 20 28 69 64 |able test.t1 (id|
# c9 20 69 6e 74 20 6e 6f 74 20 6e 75 6c 6c 29 | int not null)|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375906879/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table test.t1 (id int not null)
/*!*/;
# at 215
#130807 23:21:31 server id 1 end_log_pos 321
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# d7 |4b ac 02 52 |02 |01 00 00 00 |6a 00 00 00 |41 01 00 00 |00 00
#
# f6 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 106 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# 116 04 08 00 08 00 08 00 00 69 6e 73 65 72 74 20 69 |........insert i|
# 126 6e 74 6f 20 74 65 73 74 2e 74 31 20 28 69 64 29 |nto test.t1 (id)|
# 136 20 76 61 6c 75 65 73 20 28 31 29 | values (1)|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375906891/*!*/;
insert into test.t1 (id) values (1)
/*!*/;
# at 321
#130807 23:21:41 server id 1 end_log_pos 410
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 141 |55 ac 02 52 |02 |01 00 00 00 |59 00 00 00 |9a 01 00 00 |00 00
#
# 160 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 170 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# 180 04 08 00 08 00 08 00 00 64 72 6f 70 20 74 61 62 |........drop tab|
# 190 6c 65 20 74 65 73 74 2e 74 31 |le test.t1|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375906901/*!*/;
drop table test.t1
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#130807 23:38:51 server id 1 end_log_pos 106
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 4 |5b b0 02 52 |0f |01 00 00 00 |66 00 00 00 |6a 00 00 00 |00 00
#
# 17 04 00 35 2e 31 2e 36 33 2d 67 6f 6f 67 6c 65 2d |..5.1.63-google-|
# 27 64 65 62 75 67 2d 6c 6f 67 00 00 00 00 00 00 00 |debug-log.......|
# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
# 47 00 00 00 00 5b b0 02 52 13 38 0d 00 08 00 12 00 |....[..R.8......|
# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........|
# 67 08 08 02 |...|
#
# Event: Start: binlog v 4, server v 5.1.63-google-debug-log created 130807 23:38:51 at startup
ROLLBACK/*!*/;
BINLOG '
W7ACUg8BAAAAZgAAAGoAAAAAAAQANS4xLjYzLWdvb2dsZS1kZWJ1Zy1sb2cAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABbsAJSEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
# at 106
#130807 23:38:53 server id 1 end_log_pos 203
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 6a |5d b0 02 52 |02 |01 00 00 00 |61 00 00 00 |cb 00 00 00 |00 00
#
# 7d 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 8d 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# 9d 04 08 00 08 00 08 00 00 63 72 65 61 74 65 20 74 |........create t|
# ad 61 62 6c 65 20 74 65 73 74 2e 74 31 20 28 69 64 |able test.t1 (id|
# bd 20 69 6e 74 20 6e 6f 74 20 6e 75 6c 6c 29 | int not null)|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375907933/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table test.t1 (id int not null)
/*!*/;
# at 203
#130807 23:38:55 server id 1 end_log_pos 297
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# cb |5f b0 02 52 |02 |01 00 00 00 |5e 00 00 00 |29 01 00 00 |00 00
#
# de 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# ee 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# fe 04 08 00 08 00 08 00 00 69 6e 73 65 72 74 20 69 |........insert i|
# 10e 6e 74 6f 20 74 65 73 74 2e 74 31 20 28 69 64 29 |nto test.t1 (id)|
# 11e 20 76 61 6c 75 65 73 20 28 31 29 | values (1)|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375907935/*!*/;
insert into test.t1 (id) values (1)
/*!*/;
# at 297
#130807 23:38:57 server id 1 end_log_pos 374
# Position
# |Timestamp |Type |Master ID |Size |Master Pos |Flags
# 129 |61 b0 02 52 |02 |01 00 00 00 |4d 00 00 00 |76 01 00 00 |00 00
#
# 13c 01 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 40 |...............@|
# 14c 00 00 01 00 00 00 00 00 00 00 00 06 03 73 74 64 |.............std|
# 15c 04 08 00 08 00 08 00 00 64 72 6f 70 20 74 61 62 |........drop tab|
# 16c 6c 65 20 74 65 73 74 2e 74 31 |le test.t1|
#
# Event: Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1375907937/*!*/;
drop table test.t1
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
......@@ -275,17 +275,16 @@ FLUSH LOGS;
DROP TABLE t1;
# We create a table, patch, and load the output into it
# By using LINES STARTING BY '#' + SELECT WHERE a LIKE 'Query'
# We can easily see if a 'Query' line is missing the '#' character
# as described in the original bug
# We create a table named "patch", and load the output into it.
# By using LIKE, we can easily see if the output is missing the '#'
# character, as described in the bug.
--disable_query_log
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
### Starting master-bin.000014
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
--enable_query_log
......@@ -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 If the line is in the table, it had to have been preceded by a '#'
--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;
#
......@@ -594,3 +593,12 @@ SHOW TABLES IN test;
--exec $MYSQL_BINLOG --server-id=2 $MYSQLD_DATADIR/$master_binlog | $MYSQL
SHOW TABLES IN test;
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
......@@ -1755,6 +1755,165 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
#ifdef MYSQL_CLIENT
static void hexdump_minimal_header_to_io_cache(IO_CACHE *file,
my_off_t offset,
uchar *ptr)
{
DBUG_ASSERT(LOG_EVENT_MINIMAL_HEADER_LEN == 19);
/*
Pretty-print the first LOG_EVENT_MINIMAL_HEADER_LEN (19) bytes of the
common header, which contains the basic information about the log event.
Every event will have at least this much header, but events could contain
more headers (which must be printed by other methods, if desired).
*/
char emit_buf[120]; // Enough for storing one line
my_b_printf(file,
"# "
"|Timestamp "
"|Type "
"|Master ID "
"|Size "
"|Master Pos "
"|Flags\n");
size_t const emit_buf_written=
my_snprintf(emit_buf, sizeof(emit_buf),
"# %8llx " /* Position */
"|%02x %02x %02x %02x " /* Timestamp */
"|%02x " /* Type */
"|%02x %02x %02x %02x " /* Master ID */
"|%02x %02x %02x %02x " /* Size */
"|%02x %02x %02x %02x " /* Master Pos */
"|%02x %02x\n", /* Flags */
(ulonglong) offset, /* Position */
ptr[0], ptr[1], ptr[2], ptr[3], /* Timestamp */
ptr[4], /* Type */
ptr[5], ptr[6], ptr[7], ptr[8], /* Master ID */
ptr[9], ptr[10], ptr[11], ptr[12], /* Size */
ptr[13], ptr[14], ptr[15], ptr[16], /* Master Pos */
ptr[17], ptr[18]); /* Flags */
DBUG_ASSERT(static_cast<size_t>(emit_buf_written) < sizeof(emit_buf));
my_b_write(file, reinterpret_cast<uchar*>(emit_buf), emit_buf_written);
my_b_write(file, "#\n", 2);
}
/*
The number of bytes to print per line. Should be an even number,
and "hexdump -C" uses 16, so we'll duplicate that here.
*/
#define HEXDUMP_BYTES_PER_LINE 16
static void format_hex_line(char *emit_buff)
{
memset(emit_buff + 1, ' ',
1 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
HEXDUMP_BYTES_PER_LINE);
emit_buff[0]= '#';
emit_buff[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 1]= '|';
emit_buff[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
HEXDUMP_BYTES_PER_LINE]= '|';
emit_buff[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
HEXDUMP_BYTES_PER_LINE + 1]= '\n';
emit_buff[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
HEXDUMP_BYTES_PER_LINE + 2]= '\0';
}
static void hexdump_data_to_io_cache(IO_CACHE *file,
my_off_t offset,
uchar *ptr,
my_off_t size)
{
/*
2 = '# '
8 = address
2 = ' '
(HEXDUMP_BYTES_PER_LINE * 3 + 1) = Each byte prints as two hex digits,
plus a space
2 = ' |'
HEXDUMP_BYTES_PER_LINE = text representation
2 = '|\n'
1 = '\0'
*/
char emit_buffer[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
HEXDUMP_BYTES_PER_LINE + 2 + 1 ];
char *h,*c;
my_off_t i;
if (size == 0)
return;
format_hex_line(emit_buffer);
/*
Print the rest of the event (without common header)
*/
my_off_t starting_offset = offset;
for (i= 0,
c= emit_buffer + 2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2,
h= emit_buffer + 2 + 8 + 2;
i < size;
i++, ptr++)
{
my_snprintf(h, 4, "%02x ", *ptr);
h+= 3;
*c++= my_isprint(&my_charset_bin, *ptr) ? *ptr : '.';
/* Print in groups of HEXDUMP_BYTES_PER_LINE characters. */
if ((i % HEXDUMP_BYTES_PER_LINE) == (HEXDUMP_BYTES_PER_LINE - 1))
{
/* remove \0 left after printing hex byte representation */
*h= ' ';
/* prepare space to print address */
memset(emit_buffer + 2, ' ', 8);
/* print address */
size_t const emit_buf_written= my_snprintf(emit_buffer + 2, 9, "%8llx",
(ulonglong) starting_offset);
/* remove \0 left after printing address */
emit_buffer[2 + emit_buf_written]= ' ';
my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
sizeof(emit_buffer) - 1);
c= emit_buffer + 2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2;
h= emit_buffer + 2 + 8 + 2;
format_hex_line(emit_buffer);
starting_offset+= HEXDUMP_BYTES_PER_LINE;
}
else if ((i % (HEXDUMP_BYTES_PER_LINE / 2))
== ((HEXDUMP_BYTES_PER_LINE / 2) - 1))
{
/*
In the middle of the group of HEXDUMP_BYTES_PER_LINE, emit an extra
space in the hex string, to make two groups.
*/
*h++= ' ';
}
}
/*
There is still data left in our buffer, which means that the previous
line was not perfectly HEXDUMP_BYTES_PER_LINE characters, so write an
incomplete line, with spaces to pad out to the same length as a full
line would be, to make things more readable.
*/
if (h != emit_buffer + 2 + 8 + 2)
{
*h= ' ';
*c++= '|'; *c++= '\n';
memset(emit_buffer + 2, ' ', 8);
size_t const emit_buf_written= my_snprintf(emit_buffer + 2, 9, "%8llx",
(ulonglong) starting_offset);
emit_buffer[2 + emit_buf_written]= ' ';
/* pad unprinted area */
memset(h, ' ',
(HEXDUMP_BYTES_PER_LINE * 3 + 1) - (h - (emit_buffer + 2 + 8 + 2)));
my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
c - emit_buffer);
}
my_b_write(file, "#\n", 2);
}
/*
Log_event::print_header()
*/
......@@ -1789,86 +1948,27 @@ void Log_event::print_header(IO_CACHE* file,
{
my_b_printf(file, "\n");
uchar *ptr= (uchar*)temp_buf;
my_off_t size=
uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
my_off_t i;
/* Header len * 4 >= header len * (2 chars + space + extra space) */
char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
char *c, char_string[16+1]= {0};
/* Pretty-print event common header if header is exactly 19 bytes */
if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
{
char emit_buf[256]; // Enough for storing one line
my_b_printf(file, "# Position Timestamp Type Master ID "
"Size Master Pos Flags \n");
size_t const bytes_written=
my_snprintf(emit_buf, sizeof(emit_buf),
"# %8.8lx %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x\n",
(unsigned long) hexdump_from,
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
my_b_write(file, (uchar*) emit_buf, bytes_written);
ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
}
/* Rest of event (without common header) */
for (i= 0, c= char_string, h=hex_string;
i < size;
i++, ptr++)
{
my_snprintf(h, 4, "%02x ", *ptr);
h += 3;
*c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
if (i % 16 == 15)
{
/*
my_b_printf() does not support full printf() formats, so we
have to do it this way.
my_off_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
my_off_t hdr_len= get_header_len(print_event_info->common_header_len);
TODO: Rewrite my_b_printf() to support full printf() syntax.
*/
char emit_buf[256];
size_t const bytes_written=
my_snprintf(emit_buf, sizeof(emit_buf),
"# %8.8lx %-48.48s |%16s|\n",
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
hex_string, char_string);
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
my_b_write(file, (uchar*) emit_buf, bytes_written);
hex_string[0]= 0;
char_string[0]= 0;
c= char_string;
h= hex_string;
}
else if (i % 8 == 7) *h++ = ' ';
}
*c= '\0';
size-= hdr_len;
my_b_printf(file, "# Position\n");
/* Write the header, nicely formatted by field. */
hexdump_minimal_header_to_io_cache(file, hexdump_from, ptr);
ptr+= hdr_len;
hexdump_from+= hdr_len;
/* Print the rest of the data, mimicking "hexdump -C" output. */
hexdump_data_to_io_cache(file, hexdump_from, ptr, size);
if (hex_string[0])
{
char emit_buf[256];
size_t const bytes_written=
my_snprintf(emit_buf, sizeof(emit_buf),
"# %8.8lx %-48.48s |%s|\n",
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
hex_string, char_string);
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
my_b_write(file, (uchar*) emit_buf, bytes_written);
}
/*
need a # to prefix the rest of printouts for example those of
Rows_log_event::print_helper().
Prefix the next line so that the output from print_helper()
will appear as a comment.
*/
my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
my_b_write(file, "# Event: ", 9);
}
DBUG_VOID_RETURN;
}
......@@ -4407,7 +4507,7 @@ Start_log_event_v3::Start_log_event_v3(const char* buf,
*description_event)
:Log_event(buf, description_event)
{
buf+= description_event->common_header_len;
buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
ST_SERVER_VER_LEN);
......@@ -4762,7 +4862,7 @@ bool Format_description_log_event::write(IO_CACHE* file)
if (!dont_set_created)
created= get_time();
int4store(buff + ST_CREATED_OFFSET,created);
buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
buff[ST_COMMON_HEADER_LEN_OFFSET]= common_header_len;
/*
if checksum is requested
record the checksum-algorithm descriptor next to
......@@ -4989,9 +5089,9 @@ uint8 get_checksum_alg(const char* buf, ulong len)
DBUG_ENTER("get_checksum_alg");
DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
memcpy(version, buf +
buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET]
+ ST_SERVER_VER_OFFSET, ST_SERVER_VER_LEN);
memcpy(version,
buf + LOG_EVENT_MINIMAL_HEADER_LEN + ST_SERVER_VER_OFFSET,
ST_SERVER_VER_LEN);
version[ST_SERVER_VER_LEN - 1]= 0;
do_server_version_split(version, &version_split);
......@@ -5863,16 +5963,14 @@ Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
{
DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
uint8 header_size= description_event->common_header_len;
uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
uint ident_offset;
if (event_len < header_size)
if (event_len < LOG_EVENT_MINIMAL_HEADER_LEN)
DBUG_VOID_RETURN;
buf += header_size;
pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
ident_len = (uint)(event_len -
(header_size+post_header_len));
ident_offset = post_header_len;
buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
pos= post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
ident_len= (uint)(event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + post_header_len));
ident_offset= post_header_len;
set_if_smaller(ident_len,FN_REFLEN-1);
new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
......
......@@ -1253,6 +1253,7 @@ class Log_event
#endif
virtual Log_event_type get_type_code() = 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_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; }
bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
......@@ -2469,6 +2470,8 @@ class Start_log_event_v3: public Log_event
const Format_description_log_event* description_event);
~Start_log_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
bool write(IO_CACHE* file);
#endif
......@@ -2984,6 +2987,8 @@ class Rotate_log_event: public Log_event
my_free((void*) new_log_ident);
}
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;}
bool is_valid() const { return new_log_ident != 0; }
#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