Skip to content

GTID 4/5: Persist GTID coordinates in state, enable resume, test both modes in CI#448

Open
driv3r wants to merge 3 commits into
gtid-stage3-streamerfrom
gtid-stage4-state-resume
Open

GTID 4/5: Persist GTID coordinates in state, enable resume, test both modes in CI#448
driv3r wants to merge 3 commits into
gtid-stage3-streamerfrom
gtid-stage4-state-resume

Conversation

@driv3r

@driv3r driv3r commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Stacked PR 4 of 5 — GTID support

Base: #447. Review/merge in stack order. Contains two commits.

Commit 1 — Persist GTID coordinates in state and enable GTID resume

  • SerializableState gains BinlogCoordinateMode plus GTID counterparts of the three binlog positions (pointer + omitempty, so file/position states serialize unchanged). StateTracker stores GTID coordinates alongside file/position and selects the read path by mode.
  • Mode-aware coordinate accessors and a GTID-aware MinSourceBinlogCoordinate returning the intersection of the writer and inline-verifier GTID sets (safe resume floor); adds intersectGTIDSets (go-mysql has no intersection primitive).
  • DMLEventBase can carry explicit coordinates; BinlogStreamer stamps GTID coordinates onto events in GTID mode so BinlogWriter, inline verifier, and target verifier advance GTID-based state.
  • Ferry resume uses the mode-aware coordinates and no longer rejects GTID resume.
  • Tests: GTID state round-trip, file/position backward-compat, GTID intersection resume, tracker update/serialize/resume.

Commit 2 — Test both binlog coordinate modes in Ruby suite and CI

  • integrationferry and the Go test helper read GHOSTFERRY_BINLOG_COORDINATE_MODE.
  • Ruby harness accepts per-test :binlog_coordinate_mode + suite-wide env fallback.
  • CI matrix: ruby-test runs file_position on 5.7/8.0/8.4 and gtid on 8.0/8.4 only (GTID is MySQL 8+).
  • test_helper gains binlog_coordinate_mode / gtid_coordinate_mode?; dumped-state and progress assertions made mode-aware.
  • Progress reports mode-aware LastSuccessfulBinlogCoordinate / FinalBinlogCoordinate (alongside legacy fields); BinlogStreamer.GetStopBinlogCoordinate added.

File/position behavior and on-disk format are unchanged. Verified locally on MySQL 8.0: full Go and Ruby suites pass in both modes.

@driv3r
driv3r force-pushed the gtid-stage3-streamer branch from 7d3a39d to 4abcb71 Compare July 22, 2026 00:17
@driv3r
driv3r force-pushed the gtid-stage4-state-resume branch 2 times, most recently from 5e4845c to aa1df3b Compare July 22, 2026 13:50
@driv3r
driv3r requested review from a team, milanatshopify and pawandubey July 22, 2026 16:03
driv3r added 3 commits July 22, 2026 20:46
Make Ghostferry's serialized state and state tracker mode-aware so a
GTID-mode run can be interrupted and resumed, and route writer/verifier
state updates through GTID coordinates.

- SerializableState gains BinlogCoordinateMode plus GTID counterparts of
  the three binlog positions (pointer + omitempty, so file/position
  states serialize unchanged). StateTracker stores GTID coordinates
  alongside file/position and selects the read path by mode.
- Add mode-aware coordinate accessors and a GTID-aware
  MinSourceBinlogCoordinate that returns the intersection of the writer
  and inline-verifier GTID sets (the safe resume floor). Add
  intersectGTIDSets since go-mysql has no intersection primitive.
- DMLEventBase can carry explicit coordinates; the BinlogStreamer stamps
  GTID coordinates onto events in GTID mode so BinlogWriter, inline
  verifier, and target verifier advance GTID-based state.
- Ferry resume now uses the mode-aware coordinates and no longer rejects
  GTID resume.
- Tests: GTID state round-trip, file/position backward-compatibility,
  GTID intersection resume, and tracker update/serialize/resume.

File/position behavior and on-disk format are unchanged.
Allow the integration suite to run against file/position or GTID
coordinate mode, and exercise both in CI.

- integrationferry and the Go test helper read
  GHOSTFERRY_BINLOG_COORDINATE_MODE so every test can run in either mode.
- Ruby harness accepts a per-test :binlog_coordinate_mode and falls back
  to the suite-wide GHOSTFERRY_BINLOG_COORDINATE_MODE env var.
- GitHub Actions ruby-test matrix runs file_position on 5.7/8.0/8.4 and
  gtid on 8.0/8.4 only (GTID mode is MySQL 8+).
- test_helper gains binlog_coordinate_mode / gtid_coordinate_mode?
  helpers; dumped-state and progress assertions in callbacks and
  interrupt/resume tests are made mode-aware.
- Progress reports mode-aware LastSuccessfulBinlogCoordinate and
  FinalBinlogCoordinate (alongside the legacy file/position fields), and
  BinlogStreamer exposes GetStopBinlogCoordinate, so GTID runs report
  coherent progress.

Verified locally against MySQL 8.0: full Go and Ruby suites pass in both
file_position and gtid modes.
…tion

- Reject resume when the serialized state's coordinate mode differs from
  the configured mode, preventing cross-mode mis-routing.
- Check target-verifier coordinate presence explicitly
  (HasTargetVerifierBinlogCoordinate) rather than via IsZero(), so an
  empty (but valid) GTID set on resume is not mistaken for "absent" and
  does not skip pre-interrupt target events.
- Make intersectGTIDSets and MinSourceBinlogCoordinate fail closed: a
  parse/set-math error returns an error instead of silently falling back
  to one side, which could advance the resume floor and skip events.
  Ferry.Start propagates the error.
- Remove SetCoordinates from the exported DMLEvent interface; stamp GTID
  coordinates via an internal coordinateStamper type assertion so
  external DMLEvent implementers are unaffected. Use the cached
  NewGTIDCoordinateFromSet when stamping.
- CI: run go-test in gtid mode on MySQL 8.0/8.4 (file_position on all).
- Tests: multi-UUID intersection, fail-closed parse error, target
  verifier presence with empty GTID set.
@driv3r
driv3r force-pushed the gtid-stage3-streamer branch from 2132529 to e3d40fb Compare July 22, 2026 19:00
@driv3r
driv3r force-pushed the gtid-stage4-state-resume branch from aa1df3b to 53678c2 Compare July 22, 2026 19:00
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.

2 participants