fix: resolve MTR data inconsistency caused by binlog rotation#1
Open
dnovitski wants to merge 1 commit into
Open
fix: resolve MTR data inconsistency caused by binlog rotation#1dnovitski wants to merge 1 commit into
dnovitski wants to merge 1 commit into
Conversation
2 tasks
fc8e83e to
ad143d3
Compare
Adds parallel DML event processing via a coordinator that manages worker goroutines using MySQL's LOGICAL_CLOCK dependency tracking. Key fixes for data inconsistency: - Reset lowWaterMark on binlog rotation (sequence numbers are per-file) - Drain all workers before resetting coordinator state - Retry InnoDB deadlocks with jittered exponential backoff - Propagate fatal errors via broadcast channel - Use buffered wait channels to prevent deadlocks on error paths - Guard all lowWaterMark reads with mutex - Remove dead commented-out legacy EventsStreamer code - Add deterministic rotation regression tests Co-authored-by: meiji163 <meiji163@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ad143d3 to
4b099b0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes intermittent data inconsistency in the multithreaded replication (MTR) coordinator introduced in github/gh-ost#1454.
Root Cause
MySQL's logical clock (
last_committed,sequence_number) is per-binlog-file. Whenmax_binlog_sizetriggers a binlog rotation,sequence_numberresets to 1. However, the coordinator'slowWaterMark(lwm) was never reset — it retained the old file's high value (e.g., 65553). After rotation, allWaitForTransaction(lastCommitted)checks passed immediately (lwm >= lastCommittedtrivially true), causing transactions from the new binlog file to execute out of order.Example of the bug
This caused dependent transactions to execute concurrently, resulting in wrong final values (e.g.,
k=5046instead ofk=5047).Bugs Fixed
Bug 1: Binlog rotation state reset (THE ROOT CAUSE)
lowWaterMarknever reset on binlog rotation → stale lwm allows out-of-order executionRotateEvent, drain all busy workers, then reset lwm=-1 and clearcompletedJobs/waitingJobsmaps. The drain creates a barrier only at binlog file boundaries (acceptable overhead).Bug 2: Silent error swallowing in DML apply
applyDMLEvents()errors were logged but silently discarded;MarkTransactionCompletedwas called regardless, corrupting dependency trackingslave_transaction_retries). Propagate fatal (non-retryable) errors via a broadcast channel (failedCh).Bug 3: Wait channel deadlock on error paths
WaitForTransactionused unbuffered channels. If a waiter exited early viafailedCh, the subsequentMarkTransactionCompletedsend would block forever.Bug 4: Data race on lwm read in RotateEvent handler
if c.lowWaterMark >= 0was read without holdingc.mu, racing with concurrentMarkTransactionCompletedcalls.c.mu.Lock()/c.mu.Unlock().Verification
go build ./...✅,go vet ./...✅Performance: MTR vs Baseline
Benchmarked with 200K rows, 1000 trx/s sysbench write load for 90 seconds:
Key finding: MTR provides ~19% improvement in total migration time. The fundamental bottleneck is
executeWriteFuncswhich callsProcessEventsUntilDrained()before each row-copy chunk — under high write load, the event queue fills continuously and row-copy gets starved regardless of worker count. MTR helps by draining the queue faster with parallel workers.Files Changed
go/logic/coordinator.go— 189 insertions, 42 deletionsKnown Limitation
buildDMLEventQueryinapplier.gomutatesdmlEvent.DMLfor unique-key UPDATE operations (sets to DeleteDML then InsertDML, never restores). This is a pre-existing bug that does not affect sysbench workloads (PK-only) but could cause issues with unique-key modifications. Not addressed in this PR.