Skip to content

MDEV-39143 Replicate MySQL binary JSON to a MariaDB slave - #5700

Open
plampio wants to merge 1 commit into
13.0from
13.0-MDEV-39143
Open

plampio wants to merge 1 commit into
13.0from
13.0-MDEV-39143

Conversation

@plampio

@plampio plampio commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Let a MariaDB slave apply ROW-format binlog events from a MySQL master that contain JSON columns, both as full documents and as MySQL's partial (diff) JSON updates (PARTIAL_UPDATE_ROWS_EVENT).

Full documents reuse the slave's existing type-conversion path: the master's binlog type code 245 is mapped to the read-only mysql_json plugin's handler (table_def::field_type_handler()), and Field_longstr::rpl_conv_type_from() accepts it as a lossless conversion into a native JSON column or a lossy one into plaintext/blob, gated by slave_type_conversions as usual.

Partial updates are new. unpack_row() recognises PARTIAL_UPDATE_ROWS_EVENT, reads the after-image's value_options/partial_bits header, and for each column marked partial decodes and applies its Json_diff vector directly against the row's before-image via MariaDB's own JSON_REPLACE/JSON_INSERT/JSON_ARRAY_INSERT/JSON_REMOVE, bypassing the normal conversion-table copy step (there is no final value to copy until the diffs are applied).

An INSERT diff selects JSON_ARRAY_INSERT or JSON_INSERT based on the diff path's last leg, per MySQL's own semantics. A diff is refused, stopping the SQL thread, when the path is a from-the-end array index ('[last-N]'): MariaDB's JSON_ARRAY_INSERT resolves that case differently from MySQL, which would otherwise silently diverge from the source. Decoding a diff's JSONB value now uses Field_blob:: set_ptr() rather than Field::store(), since store() validated the raw bytes as utf8mb4 and rejected any value needing a multi-byte JSONB length (i.e. longer than 127 bytes).

Also improves the missing-plugin diagnostic: a JSON column arriving without mysql_json installed on the slave now names the plugin and the required INSTALL SONAME, instead of reporting an unknown column type.

Let a MariaDB slave apply ROW-format binlog events from a MySQL
master that contain JSON columns, both as full documents and as
MySQL's partial (diff) JSON updates (PARTIAL_UPDATE_ROWS_EVENT).
@plampio plampio self-assigned this Sep 18, 2026
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@plampio
plampio requested a review from bnestere September 18, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants