1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Files
mariadb/sql
Brandon Nesterenko 1eff7ddd81 MDEV-32570 (server): Fragment ROW replication events larger than slave_max_allowed_packet
This patch solves two problems:
  1. Rows log events cannot be transmitted to the slave if their
     size exceeds slave_max_packet_size (max 1GB at the time of
     writing this patch, i.e. MariaDB 12.3)
  2. Rows log events cannot be binlogged if they are larger than
     4GB because the common binlog event header field event_len is
     32-bits.

This patch adds support for fragmenting large Rows_log_events
through a new event type, Partial_rows_log_event. When any given
instantiation of a Rows_log_event (e.g. Write_rows_log_event, etc)
is too large to be sent to a replica (i.e. larger than the value
slave_max_allowed_packet, as configured on a replica), then the rows
event must be fragmented into sub-events (i.e.
Partial_rows_log_events), so the event can be transmitted to the
replica. The replica will then take the content of each of these
Partial_rows_log_events, and join them together into a large
Rows_log_event to be executed as normal.  Partial_rows_log_events
are written to the binary log sequentially, and the replica assembles
the events in the order they are binlogged.

To control the size of each Partial_rows_log_event, a new system
variable is added: binlog_row_event_fragment_threshold. All
Partial_rows_log_events within the same group will have this size,
except for the last, which will take up the remaining length of the
underlying Rows_log_event.

Each Partial_rows_log_event stores its sequence number (seq_no) in the
overall series of fragments, the total number of fragments needed to
re-assemble the Rows_log_event (total_fragments), a uchar for flags for
embedding extra data, and any additional data as specified by the
flags. Currently, only the first event in a grouping will have
additional data: it will set the first bit in the flags
(FL_ORIG_EVENT_SIZE) to indicate it will be storing the total size of
the underlying Rows_log_event.

The cached Rows_log_event data is fragmented into
Partial_rows_log_events as follows. The primary will still generate a
Rows_log_event to write to the binlog; however, during the actual
writing process, the raw data of the rows event is split into
fragments, each covering some continuous section of the rows data. A
Partial_rows_log_event is created for each continuous section, and the
Partial_rows_log_events are written sequentially in-place of the
too-large Rows_log_event. The original data to be fragmented will
include a header and data header; however, will not include a checksum,
as each Partial_rows_log_event will have a checksum for validation, as
well as a sequence_number and total number of fragments to ensure all
fragments are present.

The re-assembly and execution of the original Rows_log_event on the
replica happens in Partial_rows_log_event::do_apply_event(). The rgi
is extended with a memory buffer that holds all data for the
original Rows_log_event. As each Partial_rows_log_event is
ingested, its Rows_log_event content is appended to this memory
buffer. Once the last fragment has added its content, a new
Rows_log_event is created using that buffer, and executed.

A new error message is added to indicate that the slave has received an
invalid stream of Partial_rows_log_events:
ER_PARTIAL_ROWS_LOG_EVENT_BAD_STREAM.

Note this commit only adds the server logic for fragmentic and
assembling events, the client logic (mysqlbinlog) is in the next
commit.

Alternative designs considered were:
  1. Alternative 1: Change the master-slave communication protocol
     such that the master would send events in chunks of size
     slave_max_allowed_packet. Though this is still a valid idea,
     and would solve the first problem described in this commit
     message, this would still leave the limitation that
     Rows_log_events could not exceed 4GB. Eventually, this change
     should still be addressed (e.g. in MDEV-37853), and for users
     of binlog-in-engine (MDEV-34705) which supports out-of-band
     binlogging of events, this MDEV-32570 work will be superseded.
  2. Alternative 2: Create a generic “Container_log_event” with the
     intention to embed various other types of event data for
     various purposes, with flags that describe the purpose of a
     given container. This seemed overboard, as there is already a
     generic Log_event framework that provides the necessary
     abstractions to fragment/reassemble events without adding in
     extra abstractions.
  3. Alternative 3: Add a flag to Rows_log_event with semantics to
     overwrite/correct the event_len field of the common event
     header to use a 64-bit field stored in the data_header of the
     Rows_log_event; and also do alternative 1, so the master would
     send the large (> 4GB) rows event in chunks. This approach
     would add too much complexity (changing both the binlogging
     and transport layer); as well as introduce inconsistency to
     the event definition (event_len and next_event_position would
     no longer have consistent meanings).

Reviewed-by: Hemant Dangi <hemant.dangi@mariadb.com>
Acked-by: Kristian Nielsen <knielsen@knielsen-hq.org>
Signed-off-by: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
2026-01-27 12:59:23 -07:00
..
2025-03-14 12:08:56 +04:00
2025-10-25 00:19:11 +07:00
…
2024-08-12 09:32:30 +01:00
2024-11-13 16:38:53 +01:00
2024-11-10 19:22:21 +01:00
2025-07-28 21:29:29 +02:00
2024-11-05 14:00:48 -08:00
2025-09-29 18:25:09 +03:00
2024-01-19 09:07:48 +02:00
2025-03-14 12:08:56 +04:00
2025-03-14 12:08:56 +04:00
…
2024-12-02 11:35:34 +02:00
2024-12-02 17:51:17 +02:00
2024-12-02 17:51:17 +02:00
2025-09-29 18:25:09 +03:00
2024-10-30 15:11:17 +01:00
…
2025-02-06 16:46:36 +01:00
2024-12-02 11:35:34 +02:00
2023-12-21 02:14:59 +01:00
…
2024-01-27 12:09:54 +01:00
2024-01-27 12:09:54 +01:00
2024-11-08 07:17:00 +01:00
2026-01-08 12:02:45 +01:00
2026-01-08 12:02:45 +01:00
2026-01-08 12:02:45 +01:00
2026-01-25 22:16:01 +01:00
2024-11-29 13:43:17 +02:00
…
…
2024-12-05 10:11:58 +01:00
2025-10-09 09:32:33 +02:00
2025-10-09 09:32:33 +02:00
2024-11-10 19:22:21 +01:00
2025-05-22 09:22:55 +02:00
2025-09-30 12:06:31 +03:00
2026-01-08 12:02:45 +01:00
2024-12-02 17:51:17 +02:00
2024-07-08 22:40:16 +02:00
…
…
2025-03-14 12:08:56 +04:00
2025-10-08 09:05:38 +02:00
…
2024-10-03 15:59:20 +10:00
…
2025-03-14 12:08:56 +04:00
2024-11-29 12:37:46 +02:00
2024-05-30 16:04:00 +03:00
2025-04-29 11:18:00 +10:00
2025-04-02 14:07:01 +03:00
2026-01-08 12:02:45 +01:00
2026-01-08 21:41:40 +01:00
2025-05-22 09:22:55 +02:00
2025-07-31 20:55:47 +02:00
2024-06-24 13:09:47 +03:00
2025-07-31 20:55:47 +02:00
2024-12-02 17:51:17 +02:00
2025-09-29 18:25:09 +03:00
2024-07-22 15:14:50 +02:00
2025-07-31 20:55:47 +02:00
2026-01-08 12:02:45 +01:00
2025-03-14 12:08:56 +04:00
2025-11-04 12:39:27 +01:00
2025-08-03 15:01:09 +02:00
2024-12-02 17:51:17 +02:00
2026-01-08 12:02:45 +01:00
2025-09-04 18:08:39 +03:00
2025-05-03 12:06:36 +02:00
2025-07-31 20:55:47 +02:00
2024-06-24 13:09:47 +03:00
2024-12-02 17:51:17 +02:00
2024-12-02 17:51:17 +02:00
2026-01-08 21:41:40 +01:00
2026-01-08 12:02:45 +01:00
2025-05-22 09:22:55 +02:00
2026-01-05 20:34:44 +01:00
2026-01-05 20:34:44 +01:00
2026-01-08 21:41:40 +01:00
2026-01-08 12:02:45 +01:00
2025-07-28 21:29:29 +02:00
2025-07-28 21:29:29 +02:00
2025-10-25 00:19:11 +07:00
2025-03-03 11:07:56 +02:00
2026-01-08 12:02:45 +01:00
…
2025-09-29 18:25:09 +03:00
2024-06-27 10:26:09 +03:00
2025-08-04 12:05:53 +02:00
2024-12-02 17:51:17 +02:00
2025-09-19 12:31:14 +03:00
2026-01-08 12:02:45 +01:00
2026-01-08 21:41:40 +01:00
2025-04-29 11:18:00 +10:00
2025-03-14 12:08:56 +04:00
2025-07-28 21:29:29 +02:00
2024-07-03 12:45:30 +02:00
2026-01-08 12:02:45 +01:00
2026-01-08 12:02:45 +01:00
2025-01-09 09:41:38 +02:00
2026-01-08 12:02:45 +01:00
2023-12-17 11:20:43 +01:00
2024-12-02 17:51:17 +02:00
2025-09-29 18:25:09 +03:00
2025-07-31 20:55:47 +02:00
2025-10-09 17:46:33 +03:00
2026-01-08 12:02:45 +01:00
2025-07-31 20:55:47 +02:00
2025-04-29 11:18:00 +10:00
…
2026-01-05 20:34:44 +01:00
2026-01-08 12:02:45 +01:00
2026-01-08 12:02:45 +01:00
2025-03-14 12:08:56 +04:00
2024-12-02 17:51:17 +02:00
2026-01-08 21:41:40 +01:00
…
2026-01-05 20:34:44 +01:00
2025-06-18 07:50:39 +02:00
2024-01-10 18:01:46 +11:00
2026-01-08 21:41:40 +01:00
2026-01-05 20:34:44 +01:00
2025-04-29 11:18:00 +10:00
2025-09-04 18:08:39 +03:00
2024-06-24 13:09:47 +03:00
2025-03-14 12:08:56 +04:00
2024-12-02 17:51:17 +02:00
2024-12-02 11:35:34 +02:00
2025-07-31 20:55:47 +02:00
2025-08-03 15:01:09 +02:00
2025-03-14 12:08:56 +04:00
2026-01-08 12:02:45 +01:00
2025-11-28 12:56:27 +02:00
2024-06-27 10:26:09 +03:00
2024-05-10 20:02:18 +02:00
2026-01-08 12:02:45 +01:00
2026-01-08 12:02:45 +01:00
2024-10-03 13:24:43 +03:00
2024-09-09 13:50:38 +03:00
2025-04-18 17:11:01 +02:00
2024-11-08 07:17:00 +01:00
2026-01-08 12:02:45 +01:00
2025-11-11 10:34:33 +02:00
2025-07-31 20:55:47 +02:00