lotusdb icon indicating copy to clipboard operation
lotusdb copied to clipboard

the Arena function growBufSize() may have concurrency issue

Open kaminn opened this issue 2 years ago • 1 comments

https://github.com/flower-corp/lotusdb/blob/0f5d9df69c7fdcd1e8e3054e2a63f3a36441feca/arenaskl/arena.go#L125-L129

When different goroutines run to the growBufSize(), newBuf allocated by one goroutine may replaced by another. Replacement of buf and newBuf is not atomic. I just modified the skl_test.go and found this error and I don't know if it is designed that way

// TestConcurrentBasic tests concurrent writes followed by concurrent reads.
func TestConcurrentBasic(t *testing.T) {
	const n = 1000

	// Set testing flag to make it easier to trigger unusual race conditions.
	//l := NewSkiplist(NewArena(arenaSize))
       // Change NewArena size to a small one
        l := NewSkiplist(NewArena(10))
	l.testing = true

	var wg sync.WaitGroup
	for i := 0; i < n; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()

			var it Iterator
			it.Init(l)

			it.Put([]byte(fmt.Sprintf("%05d", i)), newValue(i))
		}(i)
	}
	wg.Wait()

	// Check values. Concurrent reads.
	for i := 0; i < n; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()

			var it Iterator
			it.Init(l)

			found := it.Seek([]byte(fmt.Sprintf("%05d", i)))
			require.True(t, found)
			require.EqualValues(t, newValue(i), it.Value())
		}(i)
	}
	wg.Wait()
	require.Equal(t, n, length(l))
	require.Equal(t, n, lengthRev(l))
}

kaminn avatar Apr 24 '22 13:04 kaminn

ok, I will check it.

roseduan avatar Apr 25 '22 01:04 roseduan