autoid_service: fix potential autoid decrease when leader change or close for AUTO_ID_CACHE=1 (#52602)

close pingcap/tidb#52600
This commit is contained in:
tiancaiamao
2024-04-15 20:58:35 +08:00
committed by GitHub
parent 2493981289
commit bb84d1fd2c

View File

@ -107,6 +107,14 @@ func (alloc *autoIDValue) alloc4Unsigned(ctx context.Context, store kv.Storage,
if uint64(newBase) == math.MaxUint64 {
return 0, 0, errAutoincReadFailed
}
logutil.BgLogger().Info("alloc4Unsigned from",
zap.String("category", "autoid service"),
zap.Int64("dbID", dbID),
zap.Int64("tblID", tblID),
zap.Int64("from base", alloc.base),
zap.Int64("from end", alloc.end),
zap.Int64("to base", newBase),
zap.Int64("to end", newEnd))
alloc.base, alloc.end = newBase, newEnd
}
min = alloc.base
@ -168,6 +176,14 @@ func (alloc *autoIDValue) alloc4Signed(ctx context.Context,
if newBase == math.MaxInt64 {
return 0, 0, errAutoincReadFailed
}
logutil.BgLogger().Info("alloc4Signed from",
zap.String("category", "autoid service"),
zap.Int64("dbID", dbID),
zap.Int64("tblID", tblID),
zap.Int64("from base", alloc.base),
zap.Int64("from end", alloc.end),
zap.Int64("to base", newBase),
zap.Int64("to end", newEnd))
alloc.base, alloc.end = newBase, newEnd
}
min = alloc.base
@ -301,7 +317,19 @@ func New(selfAddr string, etcdAddr []string, store kv.Storage, tlsConfig *tls.Co
func newWithCli(selfAddr string, cli *clientv3.Client, store kv.Storage) *Service {
l := owner.NewOwnerManager(context.Background(), cli, "autoid", selfAddr, autoIDLeaderPath)
service := &Service{
autoIDMap: make(map[autoIDKey]*autoIDValue),
leaderShip: l,
store: store,
}
l.SetBeOwnerHook(func() {
// Reset the map to avoid a case that a node lose leadership and regain it, then
// improperly use the stale map to serve the autoid requests.
// See https://github.com/pingcap/tidb/issues/52600
service.autoIDLock.Lock()
clear(service.autoIDMap)
service.autoIDLock.Unlock()
logutil.BgLogger().Info("leader change of autoid service, this node become owner",
zap.String("addr", selfAddr),
zap.String("category", "autoid service"))
@ -312,11 +340,7 @@ func newWithCli(selfAddr string, cli *clientv3.Client, store kv.Storage) *Servic
panic(err)
}
return &Service{
autoIDMap: make(map[autoIDKey]*autoIDValue),
leaderShip: l,
store: store,
}
return service
}
type mockClient struct {
@ -353,7 +377,10 @@ func MockForTest(store kv.Storage) autoid.AutoIDAllocClient {
// Close closes the Service and clean up resource.
func (s *Service) Close() {
if s.leaderShip != nil && s.leaderShip.IsOwner() {
s.autoIDLock.Lock()
defer s.autoIDLock.Unlock()
for k, v := range s.autoIDMap {
v.Lock()
if v.base > 0 {
err := v.forceRebase(context.Background(), s.store, k.dbID, k.tblID, v.base, v.isUnsigned)
if err != nil {
@ -364,6 +391,7 @@ func (s *Service) Close() {
zap.Error(err))
}
}
v.Unlock()
}
s.leaderShip.Cancel()
}