Skip to content

Commit

Permalink
autoid_service: fix potential 'duplicated entry' error when tidb exit…
Browse files Browse the repository at this point in the history
… for AUTO_ID_CACHE=1 tables #46445 (#46541)

close #46444
  • Loading branch information
tiancaiamao authored Aug 31, 2023
1 parent 71e6696 commit d48d236
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions autoid_service/autoid.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ func (alloc *autoIDValue) rebase4Unsigned(ctx context.Context,
}

var newBase, newEnd uint64
var oldValue int64
startTime := time.Now()
ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta)
err := kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error {
Expand All @@ -195,6 +196,7 @@ func (alloc *autoIDValue) rebase4Unsigned(ctx context.Context,
if err1 != nil {
return err1
}
oldValue = currentEnd
uCurrentEnd := uint64(currentEnd)
newBase = mathutil.Max(uCurrentEnd, requiredBase)
newEnd = mathutil.Min(math.MaxUint64-uint64(batch), newBase) + uint64(batch)
Expand All @@ -205,6 +207,13 @@ func (alloc *autoIDValue) rebase4Unsigned(ctx context.Context,
if err != nil {
return err
}

logutil.BgLogger().Info("rebase4Unsigned from",
zap.String("category", "autoid service"),
zap.Int64("dbID", dbID),
zap.Int64("tblID", tblID),
zap.Int64("from", oldValue),
zap.Uint64("to", newEnd))
alloc.base, alloc.end = int64(newBase), int64(newEnd)
return nil
}
Expand All @@ -220,22 +229,32 @@ func (alloc *autoIDValue) rebase4Signed(ctx context.Context, store kv.Storage, d
return nil
}

var newBase, newEnd int64
var oldValue, newBase, newEnd int64
startTime := time.Now()
ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta)
err := kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error {
idAcc := meta.NewMeta(txn).GetAutoIDAccessors(dbID, tblID).IncrementID(model.TableInfoVersion5)
currentEnd, err1 := idAcc.Get()
if err1 != nil {
return err1
}
oldValue = currentEnd
newBase = mathutil.Max(currentEnd, requiredBase)
newEnd = mathutil.Min(math.MaxInt64-batch, newBase) + batch
_, err1 = idAcc.Inc(newEnd - currentEnd)
return err1
})
metrics.AutoIDHistogram.WithLabelValues(metrics.TableAutoIDRebase, metrics.RetLabel(err)).Observe(time.Since(startTime).Seconds())
if err != nil {
return err
}

logutil.BgLogger().Info("rebase4Signed from",
zap.Int64("dbID", dbID),
zap.Int64("tblID", tblID),
zap.Int64("from", oldValue),
zap.Int64("to", newEnd),
zap.String("category", "autoid service"))
alloc.base, alloc.end = newBase, newEnd
return nil
}
Expand Down Expand Up @@ -273,6 +292,11 @@ func New(selfAddr string, etcdAddr []string, store kv.Storage, tlsConfig *tls.Co

l := owner.NewOwnerManager(context.Background(), cli, "autoid", selfAddr, autoIDLeaderPath)
err = l.CampaignOwner()
l.SetBeOwnerHook(func() {
logutil.BgLogger().Info("leader change of autoid service, this node become owner",
zap.String("addr", selfAddr),
zap.String("category", "autoid service"))
})
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -317,7 +341,7 @@ func MockForTest(store kv.Storage) *mockClient {

// Close closes the Service and clean up resource.
func (s *Service) Close() {
if s.leaderShip != nil {
if s.leaderShip != nil && s.leaderShip.IsOwner() {
for k, v := range s.autoIDMap {
if v.base > 0 {
err := v.forceRebase(context.Background(), s.store, k.dbID, k.tblID, v.base, v.isUnsigned)
Expand Down Expand Up @@ -465,12 +489,14 @@ func (s *Service) allocAutoID(ctx context.Context, req *autoid.AutoIDRequest) (*

func (alloc *autoIDValue) forceRebase(ctx context.Context, store kv.Storage, dbID, tblID, requiredBase int64, isUnsigned bool) error {
ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnMeta)
var oldValue int64
err := kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error {
idAcc := meta.NewMeta(txn).GetAutoIDAccessors(dbID, tblID).IncrementID(model.TableInfoVersion5)
currentEnd, err1 := idAcc.Get()
if err1 != nil {
return err1
}
oldValue = currentEnd
var step int64
if !isUnsigned {
step = requiredBase - currentEnd
Expand All @@ -484,6 +510,13 @@ func (alloc *autoIDValue) forceRebase(ctx context.Context, store kv.Storage, dbI
if err != nil {
return err
}
logutil.BgLogger().Info("forceRebase from",
zap.Int64("dbID", dbID),
zap.Int64("tblID", tblID),
zap.Int64("from", oldValue),
zap.Int64("to", requiredBase),
zap.Bool("isUnsigned", isUnsigned),
zap.String("category", "autoid service"))
alloc.base, alloc.end = requiredBase, requiredBase
return nil
}
Expand Down

0 comments on commit d48d236

Please sign in to comment.