1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log via mysqlbinlog --verbose

(This commit is exclusively for 10.2 branch. Do not merge it to 10.3)

In case of a pattern of non-STMT_END-marked Rows-log-event (A) followed by
a STMT_END marked one (B) mysqlbinlog mixes up the base64 encoded rows events
with their pseudo sql representation produced by the verbose option:
      BINLOG '
        base64 encoded data for A
        ### verbose section for A
        base64 encoded data for B
        ### verbose section for B
      '/*!*/;
In effect the produced BINLOG '...' query is not valid and is rejected with the error.
Examples of this way malformed BINLOG could have been found in binlog_row_annotate.result
that gets corrected with the patch.

The issue is fixed with introduction an auxiliary IO_CACHE to hold on the verbose
comments until the terminal STMT_END event is found. The new cache is emptied
out after two pre-existing ones are done at that time.
The correctly produced output now for the above case is as the following:
      BINLOG '
        base64 encoded data for A
        base64 encoded data for B
      '/*!*/;
        ### verbose section for A
        ### verbose section for B

Thanks to Alexey Midenkov for the problem recognition and attempt to tackle,
and to Venkatesh Duggirala who produced a patch for the upstream whose
idea is exploited here, as well as to MDEV-23077 reporter LukeXwang who
also contributed a piece of a patch aiming at this issue.
This commit is contained in:
Andrei Elkin
2020-08-11 21:45:09 +03:00
parent 9bb17ecf43
commit 6112a0f93d
9 changed files with 96 additions and 49 deletions

View File

@ -319,6 +319,24 @@ ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
DROP TABLE t1,t2;
#
# MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log with system table
#
FLUSH BINARY LOGS;
CREATE TABLE t1 (pk INT PRIMARY KEY);
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (1), (2) ON DUPLICATE KEY UPDATE pk= pk + 10;
FLUSH BINARY LOGS;
Proof: two subsequent patterns must be found
FOUND 1 /### UPDATE `test`.`t1`/ in mysqlbinlog.sql
FOUND 2 /### INSERT INTO `test`.`t1`/ in mysqlbinlog.sql
DROP TABLE t1;
SELECT * FROM t1;
pk
2
11
# Cleanup
DROP TABLE t1;
CREATE TABLE `t1` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`is_deleted` BIT(1) DEFAULT b'0',
@ -343,33 +361,33 @@ FLUSH BINARY LOGS;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 387
#<date> server id 1 end_log_pos 429 CRC32 XXX GTID 0-1-16
# at POS
#<date> server id 1 end_log_pos END_LOG_POS CRC32 XXX GTID D-S-N
/*!100101 SET @@session.skip_parallel_replication=0*//*!*/;
/*!100001 SET @@session.gtid_domain_id=0*//*!*/;
/*!100001 SET @@session.server_id=1*//*!*/;
/*!100001 SET @@session.gtid_seq_no=16*//*!*/;
/*!100001 SET @@session.gtid_seq_no=21*//*!*/;
BEGIN
/*!*/;
# at 429
# at 543
#<date> server id 1 end_log_pos 543 CRC32 XXX Annotate_rows:
# at POS
# at POS
#<date> server id 1 end_log_pos END_LOG_POS CRC32 XXX Annotate_rows:
#Q> UPDATE t1 t1 INNER JOIN t2 t2 ON t1.ref_id = t2.id
#Q> SET t1.is_deleted = TRUE
#Q> WHERE t1.id =
#<date> server id 1 end_log_pos 594 CRC32 XXX Table_map: `test`.`t1` mapped to number 34
# at 594
#<date> server id 1 end_log_pos 643 CRC32 XXX Update_rows: table id 34 flags: STMT_END_F
#<date> server id 1 end_log_pos END_LOG_POS CRC32 XXX Table_map: `test`.`t1` mapped to number TID
# at POS
#<date> server id 1 end_log_pos END_LOG_POS CRC32 XXX Update_rows: table id TID flags: STMT_END_F
### UPDATE `test`.`t1`
### WHERE
### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */
### SET
### @2=b'1' /* BIT(1) meta=1 nullable=1 is_null=0 */
### @3=X /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
# at 643
#<date> server id 1 end_log_pos 725 CRC32 XXX Query thread_id=5 exec_time=x error_code=0
# at POS
#<date> server id 1 end_log_pos END_LOG_POS CRC32 XXX Query thread_id=TID exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
SET @@session.pseudo_thread_id=5/*!*/;
SET @@session.pseudo_thread_id=TID/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
SET @@session.sql_mode=#/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
@ -379,8 +397,6 @@ SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
COMMIT
/*!*/;
# at 725
#<date> server id 1 end_log_pos 773 CRC32 XXX Rotate to master-bin.000004 pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;