Skip to content

Commit 414d942

Browse files
committed
db: don't hold DB.mu when annotating
While we expect annotations to be very cheap for the most part, they can be expensive after startup when many of the tables don't have the properties or stats populated. Now that the annotation infrastructure is thread-safe, we can annotate without holding the DB mutex.
1 parent 5e7485c commit 414d942

File tree

3 files changed

+22
-21
lines changed

3 files changed

+22
-21
lines changed

db.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -506,9 +506,10 @@ type DB struct {
506506
// validating is set to true when validation is running.
507507
validating bool
508508
}
509-
fileSizeAnnotator manifest.TableAnnotator[fileSizeByBacking]
510509
}
511510

511+
fileSizeAnnotator manifest.TableAnnotator[fileSizeByBacking]
512+
512513
// problemSpans keeps track of spans of keys within LSM levels where
513514
// compactions have failed; used to avoid retrying these compactions too
514515
// quickly.
@@ -1566,17 +1567,14 @@ func (d *DB) Close() error {
15661567
// Wait for all cleaning jobs to finish.
15671568
d.cleanupManager.Close()
15681569

1569-
// Sanity check metrics.
1570+
d.mu.Lock()
1571+
// Sanity check compaction metrics.
15701572
if invariants.Enabled {
1571-
m := d.Metrics()
1572-
if m.Compact.NumInProgress > 0 || m.Compact.InProgressBytes > 0 {
1573-
d.mu.Lock()
1574-
panic(fmt.Sprintf("invalid metrics on close:\n%s", m))
1573+
if d.mu.compact.compactingCount > 0 || d.mu.compact.downloadingCount > 0 || d.mu.versions.atomicInProgressBytes.Load() > 0 {
1574+
panic("compacting counts not 0 on close")
15751575
}
15761576
}
15771577

1578-
d.mu.Lock()
1579-
15801578
// As a sanity check, ensure that there are no zombie tables or blob files.
15811579
// A non-zero count hints at a reference count leak.
15821580
if ztbls := d.mu.versions.zombieTables.Count(); ztbls > 0 {
@@ -1854,6 +1852,9 @@ func (d *DB) Metrics() *Metrics {
18541852

18551853
d.mu.Lock()
18561854
vers := d.mu.versions.currentVersion()
1855+
vers.Ref()
1856+
defer vers.Unref()
1857+
18571858
*metrics = d.mu.versions.metrics
18581859
metrics.Compact.EstimatedDebt = d.mu.versions.picker.estimatedCompactionDebt()
18591860
metrics.Compact.InProgressBytes = d.mu.versions.atomicInProgressBytes.Load()
@@ -1936,15 +1937,6 @@ func (d *DB) Metrics() *Metrics {
19361937
metrics.BlobFiles.ObsoleteSize += pendingObsoleteFileStats.blobFilesAll.size
19371938
metrics.private.optionsFileSize = d.optionsFileSize
19381939

1939-
// TODO(jackson): Consider making these metrics optional.
1940-
aggProps := tablePropsAnnotator.MultiLevelAnnotation(vers.Levels[:])
1941-
metrics.Keys.RangeKeySetsCount = aggProps.NumRangeKeySets
1942-
metrics.Keys.TombstoneCount = aggProps.NumDeletions
1943-
1944-
delBytes := deletionBytesAnnotator.MultiLevelAnnotation(vers.Levels[:])
1945-
metrics.Table.Garbage.PointDeletionsBytesEstimate = delBytes.PointDels
1946-
metrics.Table.Garbage.RangeDeletionsBytesEstimate = delBytes.RangeDels
1947-
19481940
d.mu.versions.logLock()
19491941
metrics.private.manifestFileSize = uint64(d.mu.versions.manifest.Size())
19501942
backingCount, backingTotalSize := d.mu.versions.latest.virtualBackings.Stats()
@@ -1969,6 +1961,17 @@ func (d *DB) Metrics() *Metrics {
19691961
metrics.Table.PendingStatsCollectionCount = int64(len(d.mu.tableStats.pending))
19701962
metrics.Table.InitialStatsCollectionComplete = d.mu.tableStats.loadedInitial
19711963

1964+
d.mu.Unlock()
1965+
1966+
// TODO(jackson): Consider making these metrics optional.
1967+
aggProps := tablePropsAnnotator.MultiLevelAnnotation(vers.Levels[:])
1968+
metrics.Keys.RangeKeySetsCount = aggProps.NumRangeKeySets
1969+
metrics.Keys.TombstoneCount = aggProps.NumDeletions
1970+
1971+
delBytes := deletionBytesAnnotator.MultiLevelAnnotation(vers.Levels[:])
1972+
metrics.Table.Garbage.PointDeletionsBytesEstimate = delBytes.PointDels
1973+
metrics.Table.Garbage.RangeDeletionsBytesEstimate = delBytes.RangeDels
1974+
19721975
for i := 0; i < numLevels; i++ {
19731976
aggProps := tablePropsAnnotator.LevelAnnotation(vers.Levels[i])
19741977
metrics.Levels[i].Additional.ValueBlocksSize = aggProps.ValueBlocksSize
@@ -1978,8 +1981,6 @@ func (d *DB) Metrics() *Metrics {
19781981
blobCompressionMetrics := blobCompressionStatsAnnotator.Annotation(&vers.BlobFiles)
19791982
metrics.BlobFiles.Compression.MergeWith(&blobCompressionMetrics)
19801983

1981-
d.mu.Unlock()
1982-
19831984
metrics.BlockCache = d.opts.Cache.Metrics()
19841985
metrics.FileCache, metrics.Filter = d.fileCache.Metrics()
19851986
metrics.TableIters = d.fileCache.IterCount()

disk_usage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func (d *DB) EstimateDiskUsageByBackingType(
4848
readState := d.loadReadState()
4949
defer readState.unref()
5050

51-
sizes := d.mu.fileSizeAnnotator.VersionRangeAnnotation(readState.current, bounds)
51+
sizes := d.fileSizeAnnotator.VersionRangeAnnotation(readState.current, bounds)
5252
return sizes.totalSize, sizes.remoteSize, sizes.externalSize, nil
5353
}
5454

open.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ func Open(dirname string, opts *Options) (db *DB, err error) {
442442
d.newIters = d.fileCache.newIters
443443
d.tableNewRangeKeyIter = tableNewRangeKeyIter(d.newIters)
444444

445-
d.mu.fileSizeAnnotator = d.makeFileSizeAnnotator()
445+
d.fileSizeAnnotator = d.makeFileSizeAnnotator()
446446

447447
var previousOptionsFileNum base.DiskFileNum
448448
var previousOptionsFilename string

0 commit comments

Comments
 (0)