Skip to content

runtime RBR minimal event check#651

Merged
morgo merged 13 commits into
block:mainfrom
morgo:runtime-rbr-minimal-check
Mar 6, 2026
Merged

runtime RBR minimal event check#651
morgo merged 13 commits into
block:mainfrom
morgo:runtime-rbr-minimal-check

Conversation

@morgo
Copy link
Copy Markdown
Collaborator

@morgo morgo commented Mar 5, 2026

A Pull Request should be associated with an Issue.

We wish to have discussions in Issues. A single issue may be targeted by multiple PRs.
If you're offering a new feature or fixing anything, we'd like to know beforehand in Issues,
and potentially we'll be able to point development in a particular direction.
Further notes in https://github.com/block/spirit/blob/main/.github/CONTRIBUTING.md

Fixes #561

This refactors the DDL notification channel to be a generic cancel callback. We use the same callback if we detect that there was an RBR minimal event.

@morgo morgo force-pushed the runtime-rbr-minimal-check branch from 05d8e54 to ec7cf76 Compare March 5, 2026 22:35
@morgo morgo force-pushed the runtime-rbr-minimal-check branch from e40c029 to 64f8bf2 Compare March 6, 2026 16:35
@morgo morgo requested a review from Copilot March 6, 2026 16:37
@morgo morgo changed the title runtime RBR check runtime RBR minimal event check Mar 6, 2026
@morgo morgo marked this pull request as ready for review March 6, 2026 16:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements runtime checks for minimal Row-Based Replication (RBR) images (issue #561), detecting binlog_row_image=MINIMAL events during move/migration operations that use a buffered applier (which requires full row images). The PR also refactors DDL change notifications from a channel-based system to a CancelFunc callback pattern.

Changes:

  • Added isMinimalRowImage helper and a runtime check in processRowsEvent that returns an error when a minimal RBR event is received while a buffered applier is in use.
  • Replaced the OnDDL chan string channel + SetDDLNotificationChannel API with a CancelFunc callback in ClientConfig, simplifying the notification path and removing the need for a background goroutine in each runner.
  • Replaced panics with graceful fatalError() returns that invoke the caller's CancelFunc.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/repl/utils.go Made encodeSchemaTable unexported; removed DecodeSchemaTable; changed extractTablesFromDDLStmts return type to []schemaTable
pkg/repl/utils_test.go Updated tests to use new schemaTable type; removed tests for removed functions
pkg/repl/client.go Added isMinimalRowImage, fatalError; replaced DDL channel with CancelFunc/DDLFilterSchema; replaced panics with graceful shutdown
pkg/repl/client_test.go Updated tests for new API; added TestIsMinimalRowImage and TestProcessRowsEventMinimalRBRWithApplier
pkg/migration/runner.go Replaced ddlNotification channel + tableChangeNotification goroutine with fatalError callback
pkg/migration/runner_test.go Added TestBufferedMigrationFailsGracefullyWithMinimalRBR
pkg/move/runner.go Replaced ddlNotification channel + tableChangeNotification goroutine with fatalError callback and DDLFilterSchema
pkg/move/runner_test.go Added TestMoveFailsGracefullyWithMinimalRBR

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/move/runner.go
Comment thread pkg/repl/client.go
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

pkg/repl/client.go:625

  • After processDDLNotification calls c.fatalError(), the readStream goroutine continues running (there is no return statement after the loop that calls processDDLNotification on lines 623–625). This is inconsistent with the rows-event path where fatalError() is always followed by return (lines 605–606). As a result, after a DDL-triggered cancellation, the goroutine keeps consuming and processing binlog events until the client's internal context is eventually cancelled by Close(). While this is not a correctness issue (since callerCancelFunc is idempotent), it wastes resources and introduces an asymmetry that may complicate future maintenance.
				// For example, it won't parse [CREATE|DROP] TRIGGER statements *or*
				// ALTER USER x IDENTIFIED WITH x RETAIN CURRENT PASSWORD
				// This behavior is copied from canal:

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/move/runner.go
Comment thread pkg/repl/client.go Outdated
@morgo morgo merged commit 730cf2e into block:main Mar 6, 2026
10 checks passed
@morgo morgo deleted the runtime-rbr-minimal-check branch March 6, 2026 22:26
@morgo morgo mentioned this pull request Mar 14, 2026
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.

Add runtime checks for minimal RBR

3 participants