Skip to content

Commit

Permalink
meta: add lock at autoid.(*allocator).Base() (#40588)
Browse files Browse the repository at this point in the history
close #40584
  • Loading branch information
Dousir9 authored Jan 17, 2023
1 parent 971deb6 commit 787cb27
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
4 changes: 4 additions & 0 deletions meta/autoid/autoid.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,15 @@ func SetStep(s int64) {

// Base implements autoid.Allocator Base interface.
func (alloc *allocator) Base() int64 {
alloc.mu.Lock()
defer alloc.mu.Unlock()
return alloc.base
}

// End implements autoid.Allocator End interface.
func (alloc *allocator) End() int64 {
alloc.mu.Lock()
defer alloc.mu.Unlock()
return alloc.end
}

Expand Down
55 changes: 55 additions & 0 deletions meta/autoid/autoid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"math"
"math/rand"
"sync"
"sync/atomic"
"testing"
"time"

Expand Down Expand Up @@ -594,3 +595,57 @@ func TestAllocComputationIssue(t *testing.T) {
require.Equal(t, int64(7), min)
require.Equal(t, int64(13), max)
}

func TestIssue40584(t *testing.T) {
store, err := mockstore.NewMockStore()
require.NoError(t, err)
defer func() {
err := store.Close()
require.NoError(t, err)
}()

ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnMeta)
err = kv.RunInNewTxn(ctx, store, false, func(ctx context.Context, txn kv.Transaction) error {
m := meta.NewMeta(txn)
err = m.CreateDatabase(&model.DBInfo{ID: 1, Name: model.NewCIStr("a")})
require.NoError(t, err)
err = m.CreateTableOrView(1, &model.TableInfo{ID: 1, Name: model.NewCIStr("t")})
require.NoError(t, err)
return nil
})
require.NoError(t, err)

alloc := autoid.NewAllocator(store, 1, 1, false, autoid.RowIDAllocType)
require.NotNil(t, alloc)

finishAlloc := make(chan bool)
finishBase := make(chan bool)
var done int32 = 0

// call allocator.Alloc and allocator.Base in parallel for 3 seconds to detect data race
go func() {
for {
alloc.Alloc(ctx, 1, 1, 1)
if atomic.LoadInt32(&done) > 0 {
break
}
}
finishAlloc <- true
}()

go func() {
for {
alloc.Base()
if atomic.LoadInt32(&done) > 0 {
break
}
}
finishBase <- true
}()

runTime := time.NewTimer(time.Second * 3)
<-runTime.C
atomic.AddInt32(&done, 1)
<-finishAlloc
<-finishBase
}

0 comments on commit 787cb27

Please sign in to comment.