diff options
-rw-r--r-- | mysql-test/r/mysqlbinlog.result | 338 | ||||
-rw-r--r-- | mysql-test/std_data/mdev-4645-binlog_checksum.binlog | bin | 0 -> 386 bytes | |||
-rw-r--r-- | mysql-test/std_data/mdev-4645-binlog_group_id.binlog | bin | 0 -> 398 bytes | |||
-rw-r--r-- | mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog | bin | 0 -> 410 bytes | |||
-rw-r--r-- | mysql-test/std_data/mdev-4645-binlog_none.binlog | bin | 0 -> 374 bytes | |||
-rw-r--r-- | mysql-test/t/mysqlbinlog.test | 20 | ||||
-rw-r--r-- | sql/log_event.cc | 274 | ||||
-rw-r--r-- | sql/log_event.h | 5 |
8 files changed, 542 insertions, 95 deletions
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 3c8b2ab0a17..007ef38b413 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -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*/; diff --git a/mysql-test/std_data/mdev-4645-binlog_checksum.binlog b/mysql-test/std_data/mdev-4645-binlog_checksum.binlog Binary files differnew file mode 100644 index 00000000000..861e9b4fd67 --- /dev/null +++ b/mysql-test/std_data/mdev-4645-binlog_checksum.binlog diff --git a/mysql-test/std_data/mdev-4645-binlog_group_id.binlog b/mysql-test/std_data/mdev-4645-binlog_group_id.binlog Binary files differnew file mode 100644 index 00000000000..a9a6722bea2 --- /dev/null +++ b/mysql-test/std_data/mdev-4645-binlog_group_id.binlog diff --git a/mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog b/mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog Binary files differnew file mode 100644 index 00000000000..a936ffb139a --- /dev/null +++ b/mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog diff --git a/mysql-test/std_data/mdev-4645-binlog_none.binlog b/mysql-test/std_data/mdev-4645-binlog_none.binlog Binary files differnew file mode 100644 index 00000000000..7ceeca9e8c1 --- /dev/null +++ b/mysql-test/std_data/mdev-4645-binlog_none.binlog diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 96b18be8c37..d492af92cb2 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -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 diff --git a/sql/log_event.cc b/sql/log_event.cc index 51fa9d77267..b0380686e0f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -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)); diff --git a/sql/log_event.h b/sql/log_event.h index 39a6ce24036..9a74203757c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1253,6 +1253,7 @@ public: #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 @@ public: 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 @@ public: 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 |