Skip to content

fix(mysql): fail fast on partial JSON binlog events (PARTIAL_JSON)#4538

Merged
dtunikov merged 3 commits into
mainfrom
fix/DBI-813/partial-json-binlog-row-value-options
Jul 7, 2026
Merged

fix(mysql): fail fast on partial JSON binlog events (PARTIAL_JSON)#4538
dtunikov merged 3 commits into
mainfrom
fix/DBI-813/partial-json-binlog-row-value-options

Conversation

@dtunikov

@dtunikov dtunikov commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Problem

binlog_row_value_options is a dynamic, session-settable MySQL variable, so it can be set to PARTIAL_JSON at runtime after a mirror passes creation-time validation. When enabled, MySQL emits PARTIAL_UPDATE_ROWS_EVENT (event type 39) carrying JSON diffs instead of full column values.

go-mysql parses these into a *replication.RowsEvent, so the event reaches PeerDB's case *replication.RowsEvent: normally. But the inner event-type switch had no case for PARTIAL_UPDATE_ROWS_EVENT and no default — so the entire update (all columns, not just the JSON one) was silently dropped after its bytes were already counted as consumed. CDC advanced past it → silent data loss.

Fix

  • Add a PARTIAL_UPDATE_ROWS_EVENT case that fails fast with a new classified error (MySQLUnsupportedBinlogRowValueOptionsErrorNOTIFY_BINLOG_PARTIAL_JSON_UNSUPPORTED), instructing the user to disable binlog_row_value_options and resync.

🤖 Generated with Claude Code

When binlog_row_value_options=PARTIAL_JSON is enabled at runtime on the
source, MySQL emits PARTIAL_UPDATE_ROWS_EVENT carrying JSON diffs instead
of full values. go-mysql parses these as a *RowsEvent, but PeerDB's inner
event-type switch had no case for it and no default, so the entire update
(all columns) was silently dropped after its bytes were counted as
consumed — CDC advanced past it, causing silent data loss.

Add a PARTIAL_UPDATE_ROWS_EVENT case that fails fast with a classified
error (NOTIFY_BINLOG_PARTIAL_JSON_UNSUPPORTED) telling the user to disable
binlog_row_value_options and resync, plus a default branch so any future
rows-event subtype errors loudly instead of dropping data. The JsonDiff
value conversion now errors as a defensive backstop. Scoped to tables in
the pipe via the existing `schema != nil` guard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dtunikov

dtunikov commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

@claude

claude Bot commented Jul 6, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

1 similar comment
@claude

claude Bot commented Jul 6, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@dtunikov dtunikov closed this Jul 6, 2026
}

if _, ok := errors.AsType[*exceptions.MySQLUnsupportedBinlogRowValueOptionsError](err); ok {
return ErrorNotifyBinlogPartialJsonUnsupported, ErrorInfo{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're doing custom notification, can include AdditionalAttributes here as well

@dtunikov dtunikov reopened this Jul 7, 2026
@dtunikov dtunikov enabled auto-merge (squash) July 7, 2026 13:01
@dtunikov dtunikov merged commit 8ffb997 into main Jul 7, 2026
18 checks passed
@dtunikov dtunikov deleted the fix/DBI-813/partial-json-binlog-row-value-options branch July 7, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants