Skip to content

Commit 2ea01ff

Browse files
Giulio2002claude
authored andcommitted
[SharovBot] Fix data race between buildFiles and recalcVisibleFiles (#19590)
**[SharovBot]** Fix DATA RACE in `db/state/aggregator.go` ## Summary - `buildFiles()` calls `BeginFilesRo()` on `Domain` and `InvertedIndex` without holding `visibleFilesLock`, racing with `recalcVisibleFiles()` which writes `_visible`/`_visibleFiles` fields under the same lock - Wraps the `BeginFilesRo()` calls in `buildFiles()` with `a.visibleFilesLock.RLock()`/`RUnlock()` to synchronize with the writer, matching the pattern already used in `Aggregator.BeginFilesRo()` ## Test plan - [x] `go build ./...` passes - [x] `go test -race ./execution/verify/... -run TestHistoryVerification_WithUserTransactions` passes 3 consecutive times with no DATA RACE - [x] `go test -race ./db/state/...` passes with no DATA RACE 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9746330 commit 2ea01ff

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

db/state/aggregator.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -778,15 +778,17 @@ func (a *Aggregator) buildFiles(ctx context.Context, step kv.Step) error {
778778

779779
g, ctx := errgroup.WithContext(ctx)
780780
g.SetLimit(a.collateAndBuildWorkers)
781-
for _, d := range a.d {
781+
782+
// Use agg.BeginFilesRo() to safely snapshot visible files under visibleFilesLock,
783+
// instead of calling individual domain/ii BeginFilesRo() without synchronization.
784+
ac := a.BeginFilesRo()
785+
for id, d := range a.d {
782786
if d.Disable {
783787
continue
784788
}
785789

786790
d := d
787-
dc := d.BeginFilesRo()
788-
firstStepNotInFiles := dc.FirstStepNotInFiles()
789-
dc.Close()
791+
firstStepNotInFiles := ac.d[id].FirstStepNotInFiles()
790792
if step < firstStepNotInFiles {
791793
continue
792794
}
@@ -830,9 +832,7 @@ func (a *Aggregator) buildFiles(ctx context.Context, step kv.Step) error {
830832
}
831833

832834
ii := ii
833-
dc := ii.BeginFilesRo()
834-
firstStepNotInFiles := dc.FirstStepNotInFiles()
835-
dc.Close()
835+
firstStepNotInFiles := ac.iis[iikey].FirstStepNotInFiles()
836836
if step < firstStepNotInFiles {
837837
continue
838838
}
@@ -859,6 +859,7 @@ func (a *Aggregator) buildFiles(ctx context.Context, step kv.Step) error {
859859
return nil
860860
})
861861
}
862+
ac.Close()
862863
if err := g.Wait(); err != nil {
863864
static.CleanupOnError()
864865
return fmt.Errorf("domain collate-build: %w", err)

0 commit comments

Comments
 (0)