fix(tsm1): Fix data race of seriesKeys in deleteSeriesRange (#25268)

Add an RWMutex to allow safe concurrent 
access in deleteSeriesRange
pull/25472/head
Shiwen Cheng 2024-09-28 07:36:27 +08:00 committed by GitHub
parent 8419439e89
commit 1bc0eb4795
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 7 additions and 0 deletions

View File

@ -1675,6 +1675,9 @@ func (e *Engine) deleteSeriesRange(seriesKeys [][]byte, min, max int64) error {
// would delete it from the index.
minKey := seriesKeys[0]
// Ensure seriesKeys slice is correctly read and written concurrently in the Apply func.
var seriesKeysLock sync.RWMutex
// Apply runs this func concurrently. The seriesKeys slice is mutated concurrently
// by different goroutines setting positions to nil.
if err := e.FileStore.Apply(func(r TSMFile) error {
@ -1691,6 +1694,7 @@ func (e *Engine) deleteSeriesRange(seriesKeys [][]byte, min, max int64) error {
seriesKey, _ := SeriesAndFieldFromCompositeKey(indexKey)
// Skip over any deleted keys that are less than our tsm key
seriesKeysLock.RLock()
cmp := bytes.Compare(seriesKeys[j], seriesKey)
for j < len(seriesKeys) && cmp < 0 {
j++
@ -1699,10 +1703,13 @@ func (e *Engine) deleteSeriesRange(seriesKeys [][]byte, min, max int64) error {
}
cmp = bytes.Compare(seriesKeys[j], seriesKey)
}
seriesKeysLock.RUnlock()
// We've found a matching key, cross it out so we do not remove it from the index.
if j < len(seriesKeys) && cmp == 0 {
seriesKeysLock.Lock()
seriesKeys[j] = emptyBytes
seriesKeysLock.Unlock()
j++
}
}