-
Notifications
You must be signed in to change notification settings - Fork 188
syncer: fix syncer gtid auto switch from off to on #1723
Changes from 8 commits
b234975
0e0f8b3
785e52a
4eb2f7a
9e21c00
3ce2322
3dda7f4
deeed45
4780ff5
88fe058
a4be61c
06daec1
63caa4d
a743fae
69981e7
e8cb982
6872516
ab53df5
4c39ddf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -254,8 +254,10 @@ func (s *Server) doStartKeepAlive() { | |
} | ||
|
||
func (s *Server) stopKeepAlive() { | ||
s.kaCancel() | ||
s.kaWg.Wait() | ||
if s.kaCancel != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in which case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
s.kaCancel() | ||
s.kaWg.Wait() | ||
} | ||
} | ||
|
||
func (s *Server) restartKeepAlive() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -316,6 +316,39 @@ func CompareLocation(location1, location2 Location, cmpGTID bool) int { | |
return compareIndex(location1.Suffix, location2.Suffix) | ||
} | ||
|
||
// CompareLocationAsPossible returns: | ||
// 1 if point1 is bigger than point2 | ||
lance6716 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// 0 if point1 is equal to point2 | ||
// -1 if point1 is less than point2 | ||
// The difference is that this function will compare positions if gtid sets are both empty. | ||
func CompareLocationAsPossible(location1, location2 Location, cmpGTID bool) int { | ||
if cmpGTID { | ||
cmp, canCmp := CompareGTID(location1.gtidSet, location2.gtidSet) | ||
if canCmp { | ||
if cmp != 0 { | ||
return cmp | ||
} | ||
if cmp = compareIndex(location1.Suffix, location2.Suffix); cmp != 0 { | ||
return cmp | ||
} | ||
if location1.gtidSet != nil && location1.gtidSet.String() != "" { | ||
return cmp | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if both gtid sets are empty, but suffix are not? e.g. location1:(pos1,"",1), location2:(pos2,"",0) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think |
||
// empty GTIDSet, then compare by position | ||
log.L().Warn("both gtidSets are empty, will compare by position", zap.Stringer("location1", location1), zap.Stringer("location2", location2)) | ||
} else { | ||
// if can't compare by GTIDSet, then compare by position | ||
log.L().Warn("gtidSet can't be compared, will compare by position", zap.Stringer("location1", location1), zap.Stringer("location2", location2)) | ||
} | ||
} | ||
|
||
cmp := ComparePosition(location1.Position, location2.Position) | ||
lance6716 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if cmp != 0 { | ||
return cmp | ||
} | ||
return compareIndex(location1.Suffix, location2.Suffix) | ||
} | ||
|
||
// CompareGTID returns: | ||
// 1, true if gSet1 is bigger than gSet2 | ||
// 0, true if gSet1 is equal to gSet2 | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -30,26 +30,14 @@ import ( | |||||
"github.com/pingcap/dm/relay/common" | ||||||
) | ||||||
|
||||||
// GetGTIDsForPos tries to get GTID sets for the specified binlog position (for the corresponding txn). | ||||||
// NOTE: this method is very similar with `relay/writer/file_util.go/getTxnPosGTIDs`, unify them if needed later. | ||||||
// NOTE: this method is not well tested directly, but more tests have already been done for `relay/writer/file_util.go/getTxnPosGTIDs`. | ||||||
func GetGTIDsForPos(ctx context.Context, r Reader, endPos gmysql.Position) (gtid.Set, error) { | ||||||
// start to get and parse binlog event from the beginning of the file. | ||||||
startPos := gmysql.Position{ | ||||||
Name: endPos.Name, | ||||||
Pos: 0, | ||||||
} | ||||||
err := r.StartSyncByPos(startPos) | ||||||
if err != nil { | ||||||
return nil, err | ||||||
} | ||||||
defer r.Close() | ||||||
|
||||||
// GetGTIDsForPosStreamer tries to get GTID sets for the specified binlog position (for the corresponding txn) from a Streamer. | ||||||
func GetGTIDsForPosStreamer(ctx context.Context, r Streamer, endPos gmysql.Position) (gtid.Set, error) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
var ( | ||||||
flavor string | ||||||
latestPos uint32 | ||||||
latestGSet gmysql.GTIDSet | ||||||
nextGTIDStr string // can be recorded if the coming transaction completed | ||||||
err error | ||||||
) | ||||||
for { | ||||||
var e *replication.BinlogEvent | ||||||
|
@@ -141,6 +129,24 @@ func GetGTIDsForPos(ctx context.Context, r Reader, endPos gmysql.Position) (gtid | |||||
} | ||||||
} | ||||||
|
||||||
// GetGTIDsForPos tries to get GTID sets for the specified binlog position (for the corresponding txn). | ||||||
// NOTE: this method is very similar with `relay/writer/file_util.go/getTxnPosGTIDs`, unify them if needed later. | ||||||
// NOTE: this method is not well tested directly, but more tests have already been done for `relay/writer/file_util.go/getTxnPosGTIDs`. | ||||||
func GetGTIDsForPos(ctx context.Context, r Reader, endPos gmysql.Position) (gtid.Set, error) { | ||||||
// start to get and parse binlog event from the beginning of the file. | ||||||
startPos := gmysql.Position{ | ||||||
Name: endPos.Name, | ||||||
Pos: 0, | ||||||
} | ||||||
err := r.StartSyncByPos(startPos) | ||||||
if err != nil { | ||||||
return nil, err | ||||||
} | ||||||
defer r.Close() | ||||||
|
||||||
return GetGTIDsForPosStreamer(ctx, r, endPos) | ||||||
} | ||||||
|
||||||
// GetPreviousGTIDFromGTIDSet tries to get previous GTID sets from Previous_GTID_EVENT GTID for the specified GITD Set. | ||||||
// events should be [fake_rotate_event,format_description_event,previous_gtids_event/mariadb_gtid_list_event]. | ||||||
func GetPreviousGTIDFromGTIDSet(ctx context.Context, r Reader, gset gtid.Set) (gtid.Set, error) { | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -781,7 +781,8 @@ func (cp *RemoteCheckPoint) Load(tctx *tcontext.Context) error { | |
gset, | ||
) | ||
if isGlobal { | ||
if binlog.CompareLocation(location, binlog.NewLocation(cp.cfg.Flavor), cp.cfg.EnableGTID) > 0 { | ||
// Use CompareLocationAsPossible here to make sure checkpoint can be updated if gset is empty | ||
if binlog.CompareLocationAsPossible(location, binlog.NewLocation(cp.cfg.Flavor), cp.cfg.EnableGTID) > 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this function always called with location2 as empty location? If so, we could not be bothered to add an unit test, just simplifying the logic and tighten function name |
||
cp.globalPoint = newBinlogPoint(location, location, nil, nil, cp.cfg.EnableGTID) | ||
cp.logCtx.L().Info("fetch global checkpoint from DB", log.WrapStringerField("global checkpoint", cp.globalPoint)) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# diff Configuration. | ||
|
||
log-level = "info" | ||
|
||
chunk-size = 1000 | ||
|
||
check-thread-count = 4 | ||
|
||
sample-percent = 100 | ||
|
||
use-checksum = true | ||
|
||
fix-sql-file = "fix.sql" | ||
|
||
# tables need to check. | ||
[[check-tables]] | ||
schema = "adjust_gtid" | ||
tables = ["~t.*"] | ||
|
||
[[table-config]] | ||
schema = "adjust_gtid" | ||
table = "t1" | ||
|
||
[[table-config.source-tables]] | ||
instance-id = "source-1" | ||
schema = "adjust_gtid" | ||
table = "t1" | ||
|
||
[[table-config]] | ||
schema = "adjust_gtid" | ||
table = "t2" | ||
|
||
[[table-config.source-tables]] | ||
instance-id = "source-2" | ||
schema = "adjust_gtid" | ||
table = "t2" | ||
|
||
[[source-db]] | ||
host = "127.0.0.1" | ||
port = 3306 | ||
user = "root" | ||
password = "123456" | ||
instance-id = "source-1" | ||
|
||
[[source-db]] | ||
host = "127.0.0.1" | ||
port = 3307 | ||
user = "root" | ||
password = "123456" | ||
instance-id = "source-2" | ||
|
||
[target-db] | ||
host = "127.0.0.1" | ||
port = 4000 | ||
user = "test" | ||
password = "123456" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Master Configuration. | ||
master-addr = ":8261" | ||
advertise-addr = "127.0.0.1:8261" | ||
|
||
rpc-timeout = "30s" | ||
auto-compaction-retention = "3s" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't remember why we need this helper function now. maybe the process won't exit after this test function returns?
if so, I think the reason may be that lthe test function should be named
TestMain
notTestRunMain
, please check if this works.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ref https://golang.org/pkg/testing/#hdr-Main