canal: add transactional position sync#1144
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a TransactionalPosSync configuration option to prevent syncing binlog positions for unfinished transactions. The implementation skips position synchronization on 'BEGIN' query events, forces synchronization on 'XID' events, and omits the final sync during service shutdown when enabled. A new helper function isBeginQuery and comprehensive unit tests were added. Feedback suggests optimizing isBeginQuery by using the bytes package to avoid unnecessary string allocations in a hot path.
|
/cc @dveeden |
There was a problem hiding this comment.
Pull request overview
Adds an opt-in “transactional position sync” mode to Canal to avoid syncing binlog/GTID positions at transaction start (e.g., BEGIN) and instead force syncing at transaction commit boundaries, improving crash-safety for GTID-based consumers.
Changes:
- Introduce
Config.TransactionalPosSyncto alter position sync semantics (skipBEGIN, force sync onXIDandCOMMIT). - Update
Canal.Close()to avoid the final forcedOnPosSyncedcall when transactional mode is enabled. - Add offline unit tests covering legacy vs transactional behavior, forced sync behavior, and close behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
canal/sync.go |
Implements transactional position sync logic (skip BEGIN sync; force sync on XID/COMMIT). |
canal/sync_test.go |
Adds offline unit tests validating new/legacy position sync semantics. |
canal/config.go |
Adds TransactionalPosSync config flag with TOML support and docs. |
canal/canal.go |
Skips forced OnPosSynced on Close() when transactional mode is enabled. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@serprex I have merged #1153. Can you take a look at this PR? For example, do you think it's good to add a new config item, the default behaviour will not run this logic? |
|
imo you should drop this PR & take #1153 as the correct way about things but take my opinion with a grain of salt, peerdb doesn't use canal, so I have no context on its use / design |
We also don't use canal API, so I can't decide if it's worth adding an option to keep wrong but more compatible behaviour. |
|
IMHO #1153 breaks other things. Specifically, as of right now, All that session meta-data, e.g. the encoding, the variables, are essential for one of my use cases and there is no other way to capture these details. Besides, |
Fixes #1090.
Summary
Config.TransactionalPosSyncas an opt-in mode for crash-safe Canal position sync semantics.OnPosSyncedforBEGINQueryEvent so the GTID set is not advanced before the transaction is processed.force=true, and avoid the final forcedOnPosSyncedfromCanal.Close().BEGINdetection.Validation
go test ./canal -run 'TestIsBeginQuery|TestHandleEventBeginPositionSync|TestHandleEventXIDForcePositionSync|TestClosePositionSync|TestGetShowBinaryLogQuery'go test ./canal -run '^$'go test ./... -run '^$'git diff --checkFull
go test ./canalrequires a local MySQL instance; without one it fails at127.0.0.1:3306: connect: connection refused.