[Commits] Rev 3674: MDEV-4645: Incorrect reads of frozen binlog events; FDE corrupted in relay log in file:///home/bell/maria/bzr/work-maria-10.0-base-MDEV-4645/

sanja at montyprogram.com sanja at montyprogram.com
Mon Aug 12 17:33:33 EEST 2013


At file:///home/bell/maria/bzr/work-maria-10.0-base-MDEV-4645/

------------------------------------------------------------
revno: 3674
revision-id: sanja at montyprogram.com-20130812143331-4bhdor0kgp9c9onv
parent: igor at askmonty.org-20130806203318-esxb7kpq9kab0i97
committer: sanja at montyprogram.com
branch nick: work-maria-10.0-base-MDEV-4645
timestamp: Mon 2013-08-12 17:33:31 +0300
message:
  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
-------------- next part --------------
=== modified file 'mysql-test/r/mysqlbinlog.result'
--- a/mysql-test/r/mysqlbinlog.result	2013-04-15 08:55:27 +0000
+++ b/mysql-test/r/mysqlbinlog.result	2013-08-12 14:33:31 +0000
@@ -630,7 +630,7 @@ We expect this value to be 2 (one for th
 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*/;

=== added file 'mysql-test/std_data/mdev-4645-binlog_checksum.binlog'
���������������� ���������� a/mysql-test/std_data/mdev-4645-binlog_checksum.binlog	1970-01-01 00:00:00 +0000 �� b/mysql-test/std_data/mdev-4645-binlog_checksum.binlog	2013-08-12 14:33:31 +0000 ����������������������

=== added file 'mysql-test/std_data/mdev-4645-binlog_group_id.binlog'
���������������� ���������� a/mysql-test/std_data/mdev-4645-binlog_group_id.binlog	1970-01-01 00:00:00 +0000 �� b/mysql-test/std_data/mdev-4645-binlog_group_id.binlog	2013-08-12 14:33:31 +0000 ����������������������

=== added file 'mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog'
���������������� ���������� a/mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog	1970-01-01 00:00:00 +0000 �� b/mysql-test/std_data/mdev-4645-binlog_group_id_checksum.binlog	2013-08-12 14:33:31 +0000 ����������������������

=== added file 'mysql-test/std_data/mdev-4645-binlog_none.binlog'
���������������� ���������� a/mysql-test/std_data/mdev-4645-binlog_none.binlog	1970-01-01 00:00:00 +0000 �� b/mysql-test/std_data/mdev-4645-binlog_none.binlog	2013-08-12 14:33:31 +0000 ����������������������

=== modified file 'mysql-test/t/mysqlbinlog.test'
--- a/mysql-test/t/mysqlbinlog.test	2013-03-26 09:35:34 +0000
+++ b/mysql-test/t/mysqlbinlog.test	2013-08-12 14:33:31 +0000
@@ -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_
 --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

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2013-07-17 19:24:29 +0000
+++ b/sql/log_event.cc	2013-08-12 14:33:31 +0000
@@ -1755,6 +1755,165 @@ Log_event* Log_event::read_log_event(con
 
 #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* f
   {
     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;
+    my_off_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
+    my_off_t hdr_len= get_header_len(print_event_info->common_header_len);
 
-      *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
+    size-= hdr_len;
 
-      if (i % 16 == 15)
-      {
-        /*
-          my_b_printf() does not support full printf() formats, so we
-          have to do it this way.
+    my_b_printf(file, "# Position\n");
 
-          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';
+    /* 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(c
                                        *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);
@@ -4761,7 +4861,7 @@ bool Format_description_log_event::write
   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;
   memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET + 1, (uchar*) post_header_len,
          LOG_EVENT_TYPES);
   /*
@@ -4987,9 +5087,9 @@ uint8 get_checksum_alg(const char* buf,
   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);
@@ -5861,16 +5961,14 @@ Rotate_log_event::Rotate_log_event(const
 {
   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));

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2013-07-17 19:24:29 +0000
+++ b/sql/log_event.h	2013-08-12 14:33:31 +0000
@@ -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



More information about the commits mailing list