From d5b5c66b769505c60cfecee4e3e9efe749632064 Mon Sep 17 00:00:00 2001 From: Bulat Aikaev Date: Mon, 24 Jun 2024 13:22:45 -0600 Subject: [PATCH] fix(canal): handle fake rotate events correctly for MariaDB 11.4 After upgrading to MariaDB 11.4, the canal module stopped detecting row updates within transactions due to incorrect handling of fake rotate events. MariaDB 11.4 does not set LogPos for certain events, causing these events to be ignored. This fix modifies the handling to consider fake rotate events only for ROTATE_EVENTs with timestamp = 0, aligning with MariaDB and MySQL documentation. --- canal/sync.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/canal/sync.go b/canal/sync.go index d6ce44c6b..9fcc676ec 100644 --- a/canal/sync.go +++ b/canal/sync.go @@ -47,22 +47,22 @@ func (c *Canal) runSyncBinlog() error { // Update the delay between the Canal and the Master before the handler hooks are called c.updateReplicationDelay(ev) - // If log pos equals zero then the received event is a fake rotate event and - // contains only a name of the next binlog file - // See https://github.com/mysql/mysql-server/blob/8e797a5d6eb3a87f16498edcb7261a75897babae/sql/rpl_binlog_sender.h#L235 - // and https://github.com/mysql/mysql-server/blob/8cc757da3d87bf4a1f07dcfb2d3c96fed3806870/sql/rpl_binlog_sender.cc#L899 - if ev.Header.LogPos == 0 { - switch e := ev.Event.(type) { - case *replication.RotateEvent: + switch e := ev.Event.(type) { + case *replication.RotateEvent: + // If the timestamp equals zero, the received rotate event is a fake rotate event + // and contains only the name of the next binlog file. Its log position should be + // ignored. + // See https://github.com/mysql/mysql-server/blob/8e797a5d6eb3a87f16498edcb7261a75897babae/sql/rpl_binlog_sender.h#L235 + // and https://github.com/mysql/mysql-server/blob/8cc757da3d87bf4a1f07dcfb2d3c96fed3806870/sql/rpl_binlog_sender.cc#L899 + if ev.Header.Timestamp == 0 { fakeRotateLogName := string(e.NextLogName) c.cfg.Logger.Infof("received fake rotate event, next log name is %s", e.NextLogName) + if fakeRotateLogName != c.master.Position().Name { c.cfg.Logger.Info("log name changed, the fake rotate event will be handled as a real rotate event") } else { continue } - default: - continue } }