From b86fa8f40fd11c9679eab67148262238f1aee85e Mon Sep 17 00:00:00 2001 From: Zhao Junwang Date: Thu, 5 Nov 2020 10:03:53 +0800 Subject: [PATCH] Bug#101450 mysqlbinlog with start-position not show right FDE pos Description: When specify the --start-position=N to the the events that begin at position N and after, the output doesn't give the right Format_description_log_event start postion. See the difference in `How to repeat section` The reason for this lay in read_fdle function. Since this function going to work for both binlog and relay-log, after read the first FDE, it continue to read some events(PREVIOUS_GTIDS_LOG_EVENT or ROTATE_EVENT) until it see another FDE or some other event. So if this is a binlog, problem occurs, the code will forward the field `m_event_start_pos` that bigger than 4. How to repeat: without --start-position [root@localhost data]# mysqlbinlog --hexdump binlog.000001 | head -n20 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #201103 7:15:08 server id 1 end_log_pos 125 CRC32 0xfc7e724a # Position Timestamp Type Master ID Size Master Pos Flags # 00000004 cc 49 a1 5f 0f 01 00 00 00 79 00 00 00 7d 00 00 00 01 00 # 00000017 04 00 38 2e 30 2e 32 32 2d 64 65 62 75 67 00 00 |..8.0.22.debug..| # 00000027 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| # 00000037 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| # 00000047 00 00 00 00 cc 49 a1 5f 13 00 0d 00 08 00 00 00 |.....I..........| # 00000057 00 04 00 04 00 00 00 61 00 04 1a 08 00 00 00 08 |.......a........| # 00000067 08 08 02 00 00 00 0a 0a 0a 2a 2a 00 12 34 00 0a |.............4..| # 00000077 28 01 4a 72 7e fc |..Jr..| # Start: binlog v 4, server v 8.0.22-debug created 201103 7:15:08 at startup # Warning: this binlog is either in use or was not closed properly. ROLLBACK/*!*/; BINLOG ' zEmhXw8BAAAAeQAAAH0AAAABAAQAOC4wLjIyLWRlYnVnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAADMSaFfEwANAAgAAAAABAAEAAAAYQAEGggAAAAICAgCAAAACgoKKioAEjQA [root@localhost data]# with --start-position [root@localhost data]# mysqlbinlog --start-position=523 binlog.000001 | head -n20 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 156 #201103 7:15:08 server id 1 end_log_pos 125 CRC32 0xfc7e724a Start: binlog v 4, server v 8.0.22-debug created 201103 7:15:08 at startup # Warning: this binlog is either in use or was not closed properly. ROLLBACK/*!*/; BINLOG ' zEmhXw8BAAAAeQAAAH0AAAABAAQAOC4wLjIyLWRlYnVnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAADMSaFfEwANAAgAAAAABAAEAAAAYQAEGggAAAAICAgCAAAACgoKKioAEjQA CigBSnJ+/A== '/*!*/; # at 523 #201103 7:22:30 server id 1 end_log_pos 640 CRC32 0x048ab7b8 Query thread_id=11 exec_time=0 error_code=0 Xid = 10 SET TIMESTAMP=1604406150/*!*/; SET @@session.pseudo_thread_id=11/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1168113696/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8mb4 *//*!*/; [root@localhost data]# --- sql/binlog_reader.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sql/binlog_reader.h b/sql/binlog_reader.h index 43b240d15e6..b1a4e4ce5e1 100644 --- a/sql/binlog_reader.h +++ b/sql/binlog_reader.h @@ -377,6 +377,8 @@ class Basic_binlog_file_reader { [Rotate_event] : In the case rotating relaylog, no Rotate here Format_description_event : master's Format_description_event */ + int fdl_cnt = 0; + my_off_t first_fde_pos = position(); while (position() < offset) { m_event_start_pos = position(); @@ -385,6 +387,7 @@ class Basic_binlog_file_reader { if (ev == nullptr) break; if (ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT) { + fdl_cnt++; delete fdle; fdle = dynamic_cast(ev); m_fde = *fdle; @@ -400,6 +403,9 @@ class Basic_binlog_file_reader { delete fdle; return nullptr; } + if (fdl_cnt == 1 && first_fde_pos != m_event_start_pos) { + m_event_start_pos = first_fde_pos; + } return fdle; } };