Skip to content

Commit 787cb27

Browse files
authored
meta: add lock at autoid.(*allocator).Base() (#40588)
close #40584
1 parent 971deb6 commit 787cb27

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

meta/autoid/autoid.go

+4
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,15 @@ func SetStep(s int64) {
285285

286286
// Base implements autoid.Allocator Base interface.
287287
func (alloc *allocator) Base() int64 {
288+
alloc.mu.Lock()
289+
defer alloc.mu.Unlock()
288290
return alloc.base
289291
}
290292

291293
// End implements autoid.Allocator End interface.
292294
func (alloc *allocator) End() int64 {
295+
alloc.mu.Lock()
296+
defer alloc.mu.Unlock()
293297
return alloc.end
294298
}
295299

meta/autoid/autoid_test.go

+55
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"math"
2121
"math/rand"
2222
"sync"
23+
"sync/atomic"
2324
"testing"
2425
"time"
2526

@@ -594,3 +595,57 @@ func TestAllocComputationIssue(t *testing.T) {
594595
require.Equal(t, int64(7), min)
595596
require.Equal(t, int64(13), max)
596597
}
598+
599+
func TestIssue40584(t *testing.T) {
600+
store, err := mockstore.NewMockStore()
601+
require.NoError(t, err)
602+
defer func() {
603+
err := store.Close()
604+
require.NoError(t, err)
605+
}()
606+
607+
ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnMeta)
608+
err = kv.RunInNewTxn(ctx, store, false, func(ctx context.Context, txn kv.Transaction) error {
609+
m := meta.NewMeta(txn)
610+
err = m.CreateDatabase(&model.DBInfo{ID: 1, Name: model.NewCIStr("a")})
611+
require.NoError(t, err)
612+
err = m.CreateTableOrView(1, &model.TableInfo{ID: 1, Name: model.NewCIStr("t")})
613+
require.NoError(t, err)
614+
return nil
615+
})
616+
require.NoError(t, err)
617+
618+
alloc := autoid.NewAllocator(store, 1, 1, false, autoid.RowIDAllocType)
619+
require.NotNil(t, alloc)
620+
621+
finishAlloc := make(chan bool)
622+
finishBase := make(chan bool)
623+
var done int32 = 0
624+
625+
// call allocator.Alloc and allocator.Base in parallel for 3 seconds to detect data race
626+
go func() {
627+
for {
628+
alloc.Alloc(ctx, 1, 1, 1)
629+
if atomic.LoadInt32(&done) > 0 {
630+
break
631+
}
632+
}
633+
finishAlloc <- true
634+
}()
635+
636+
go func() {
637+
for {
638+
alloc.Base()
639+
if atomic.LoadInt32(&done) > 0 {
640+
break
641+
}
642+
}
643+
finishBase <- true
644+
}()
645+
646+
runTime := time.NewTimer(time.Second * 3)
647+
<-runTime.C
648+
atomic.AddInt32(&done, 1)
649+
<-finishAlloc
650+
<-finishBase
651+
}

0 commit comments

Comments
 (0)