Bug #102191 Parsing incorrectly extra row info of binlog
Submitted: 8 Jan 2021 6:26 Modified: 2 Jun 2021 9:47
Reporter: Zhang JiYang Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:8.0.22 OS:Any
Assigned to: CPU Architecture:Any
Tags: binlog mysqlbinlog partition

[8 Jan 2021 6:26] Zhang JiYang
Description:
Mysqld / mysql client (like mysqlbinlog) parses incorrectly partition info from binlog, if:
1. there is a table with more than 128 partitions
2. do a DML involved with the last partition

mysqlbinlog parses partition id wrongly:
Extra row info for partitioning: partition: 65408

where the partition id (65408) is incorrect and it should be 128.

How to repeat:
# It's easy to repeat:

CREATE TABLE foo (
    id INT primary key
)
PARTITION BY RANGE( id ) (
  PARTITION p0 VALUES LESS THAN (0),
  PARTITION p1 VALUES LESS THAN (1),
  PARTITION p2 VALUES LESS THAN (2),
  PARTITION p3 VALUES LESS THAN (3),
  ...
  PARTITION p126 VALUES LESS THAN (126),
  PARTITION p127 VALUES LESS THAN (127),
  PARTITION p128 VALUES LESS THAN (128)
);

# First, the following is the expected behavior
insert into foo values (126);

# The DML was written into binlog, and use mysqlbinlog to print verbose.
bin/mysqlbinlog -vv --base64-output=decode-row master-bin.000001

# then you will see the right partition id info like:
```
...
### Extra row info for partitioning: partition: 127
...
```

# Then, let's construct a use case that produces a bug
insert into foo values (127);

# The DML was written into binlog, and use mysqlbinlog to print verbose.
bin/mysqlbinlog -vv --base64-output=decode-row master-bin.000001

# then you will see the wrong partition id info like:
```
...
### Extra row info for partitioning: partition: 65408
...
```

Suggested fix:
binary_log::Rows_event::Rows_event(const char *buf, const Format_description_event *fde)
  --> binary_log::Event_reader::read<unsigned short>

--- a/libbinlogevents/include/event_reader.h
+++ b/libbinlogevents/include/event_reader.h
@@ -267,7 +267,7 @@ class Event_reader {
       return 0;
     }
     T value = 0;
-    value = (T) * (m_ptr);
+    value = (T) (*((const T*)m_ptr));
     m_ptr = m_ptr + sizeof(T);
     return value;
   }
[8 Jan 2021 7:25] MySQL Verification Team
Hello zanye zjy,

Thank you for the report and test case.

regards,
Umesh
[2 Jun 2021 9:47] Margaret Fisher
Posted by developer:
 
Changelog entry added for MySQL 8.0.26:

After a DML operation was performed on the last partition of a table with more than 128 partitions, MySQL Server and MySQL clients (such as mysqlbinlog) parsed the event information from the binary log incorrectly, resulting in an inaccurate partition ID being stated. The information is now read using an event reader function that is endianness independent.