Skip to content

Commit 7dc8e55

Browse files
committed
db: move latest version state into a shared struct
Consolidate the various fields that hold mutable state describing the latest version. Consolidating helps highlight the distinction that this state is expected to be mutated, unlike an immutable manifest.Version. Additonally, this prepares for passing additional mutable state into the compaction picker so that the compaction picker is capable of picking blob file rewrite compactions.
1 parent 28e2c9d commit 7dc8e55

12 files changed

+168
-167
lines changed

checkpoint.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,10 @@ func (d *DB) Checkpoint(
197197
optionsFileNum := d.optionsFileNum
198198

199199
virtualBackingFiles := make(map[base.DiskFileNum]struct{})
200-
d.mu.versions.virtualBackings.ForEach(func(backing *manifest.TableBacking) {
200+
d.mu.versions.latest.virtualBackings.ForEach(func(backing *manifest.TableBacking) {
201201
virtualBackingFiles[backing.DiskFileNum] = struct{}{}
202202
})
203-
versionBlobFiles := d.mu.versions.blobFiles.Metadatas()
203+
versionBlobFiles := d.mu.versions.latest.blobFiles.Metadatas()
204204

205205
// Acquire the logs while holding mutexes to ensure we don't race with a
206206
// flush that might mark a log that's relevant to `current` as obsolete

checkpoint_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ func testCheckpointImpl(t *testing.T, ddFile string, createOnShared bool) {
151151
d := dbs[td.CmdArgs[0].String()]
152152
d.mu.Lock()
153153
d.mu.versions.logLock()
154-
fileNums := d.mu.versions.virtualBackings.DiskFileNums()
154+
fileNums := d.mu.versions.latest.virtualBackings.DiskFileNums()
155155
d.mu.versions.logUnlock()
156156
d.mu.Unlock()
157157

compaction.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ func (d *DB) addInProgressCompaction(c *compaction) {
11791179
if isIntraL0 {
11801180
l0Inputs = append(l0Inputs, c.outputLevel.files)
11811181
}
1182-
if err := d.mu.versions.l0Organizer.UpdateStateForStartedCompaction(l0Inputs, isBase); err != nil {
1182+
if err := d.mu.versions.latest.l0Organizer.UpdateStateForStartedCompaction(l0Inputs, isBase); err != nil {
11831183
d.opts.Logger.Fatalf("could not update state for compaction: %s", err)
11841184
}
11851185
}
@@ -1236,7 +1236,7 @@ func (d *DB) clearCompactingState(c *compaction, rollback bool) {
12361236
// may be able to pick a better compaction (though when this compaction
12371237
// succeeded we've also cleared the cache in UpdateVersionLocked).
12381238
defer d.mu.versions.logUnlockAndInvalidatePickedCompactionCache()
1239-
d.mu.versions.l0Organizer.InitCompactingFileInfo(l0InProgress)
1239+
d.mu.versions.latest.l0Organizer.InitCompactingFileInfo(l0InProgress)
12401240
}()
12411241
}
12421242

@@ -1593,7 +1593,7 @@ func (d *DB) flush1() (bytesFlushed uint64, err error) {
15931593
}
15941594
}
15951595

1596-
c, err := newFlush(d.opts, d.mu.versions.currentVersion(), d.mu.versions.l0Organizer,
1596+
c, err := newFlush(d.opts, d.mu.versions.currentVersion(), d.mu.versions.latest.l0Organizer,
15971597
d.mu.versions.picker.getBaseLevel(), d.mu.mem.queue[:n], d.timeNow(), d.TableFormat(), d.determineCompactionValueSeparation)
15981598
if err != nil {
15991599
return 0, err
@@ -2061,7 +2061,7 @@ func (d *DB) tryScheduleDownloadCompactions(env compactionEnv, maxConcurrentDown
20612061
break
20622062
}
20632063
download := d.mu.compact.downloads[i]
2064-
switch d.tryLaunchDownloadCompaction(download, vers, d.mu.versions.l0Organizer, env, maxConcurrentDownloads) {
2064+
switch d.tryLaunchDownloadCompaction(download, vers, d.mu.versions.latest.l0Organizer, env, maxConcurrentDownloads) {
20652065
case launchedCompaction:
20662066
started = true
20672067
continue
@@ -2080,7 +2080,8 @@ func (d *DB) pickManualCompaction(env compactionEnv) (pc *pickedCompaction) {
20802080
v := d.mu.versions.currentVersion()
20812081
for len(d.mu.compact.manual) > 0 {
20822082
manual := d.mu.compact.manual[0]
2083-
pc, retryLater := newPickedManualCompaction(v, d.mu.versions.l0Organizer, d.opts, env, d.mu.versions.picker.getBaseLevel(), manual)
2083+
pc, retryLater := newPickedManualCompaction(v, d.mu.versions.latest.l0Organizer,
2084+
d.opts, env, d.mu.versions.picker.getBaseLevel(), manual)
20842085
if pc != nil {
20852086
return pc
20862087
}

compaction_picker.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -599,16 +599,14 @@ func canCompactTables(
599599
// installed).
600600
func newCompactionPickerByScore(
601601
v *manifest.Version,
602-
l0Organizer *manifest.L0Organizer,
603-
virtualBackings *manifest.VirtualBackings,
602+
lvs *latestVersionState,
604603
opts *Options,
605604
inProgressCompactions []compactionInfo,
606605
) *compactionPickerByScore {
607606
p := &compactionPickerByScore{
608-
opts: opts,
609-
vers: v,
610-
l0Organizer: l0Organizer,
611-
virtualBackings: virtualBackings,
607+
opts: opts,
608+
vers: v,
609+
latestVersionState: lvs,
612610
}
613611
p.initLevelMaxBytes(inProgressCompactions)
614612
return p
@@ -694,16 +692,16 @@ func totalCompensatedSize(iter iter.Seq[*manifest.TableMetadata]) uint64 {
694692
type compactionPickerByScore struct {
695693
opts *Options
696694
vers *manifest.Version
697-
// Unlike vers, which is immutable and the latest version when this picker is
698-
// created, l0Organizer represents the mutable L0 state of the latest version.
699-
// This means that at some point in the future a compactionPickerByScore
700-
// created in the past will have mutually inconsistent state in vers and
701-
// l0Organizer. This is not a problem since (a) a new picker is created in
702-
// UpdateVersionLocked when a new version is installed, and (b) only the
703-
// latest picker is used for picking compactions. This is ensured by holding
704-
// versionSet.logLock for both (a) and (b).
705-
l0Organizer *manifest.L0Organizer
706-
virtualBackings *manifest.VirtualBackings
695+
// Unlike vers, which is immutable and the latest version when this picker
696+
// is created, latestVersionState represents the mutable state of the latest
697+
// version. This means that at some point in the future a
698+
// compactionPickerByScore created in the past will have mutually
699+
// inconsistent state in vers and latestVersionState. This is not a problem
700+
// since (a) a new picker is created in UpdateVersionLocked when a new
701+
// version is installed, and (b) only the latest picker is used for picking
702+
// compactions. This is ensured by holding versionSet.logLock for both (a)
703+
// and (b).
704+
latestVersionState *latestVersionState
707705
// The level to target for L0 compactions. Levels L1 to baseLevel must be
708706
// empty.
709707
baseLevel int
@@ -939,7 +937,7 @@ func (p *compactionPickerByScore) calculateLevelScores(
939937
scores[i].level = i
940938
scores[i].outputLevel = i + 1
941939
}
942-
l0FillFactor := calculateL0FillFactor(p.vers, p.l0Organizer, p.opts, inProgressCompactions)
940+
l0FillFactor := calculateL0FillFactor(p.vers, p.latestVersionState.l0Organizer, p.opts, inProgressCompactions)
943941
scores[0] = candidateLevelInfo{
944942
outputLevel: p.baseLevel,
945943
fillFactor: l0FillFactor,
@@ -1268,7 +1266,7 @@ func (p *compactionPickerByScore) getCompactionConcurrency() int {
12681266
// l0ReadAmp / p.opts.Experimental.L0CompactionConcurrency extra compactions.
12691267
l0ReadAmpCompactions := 0
12701268
if p.opts.Experimental.L0CompactionConcurrency > 0 {
1271-
l0ReadAmp := p.l0Organizer.MaxDepthAfterOngoingCompactions()
1269+
l0ReadAmp := p.latestVersionState.l0Organizer.MaxDepthAfterOngoingCompactions()
12721270
l0ReadAmpCompactions = (l0ReadAmp / p.opts.Experimental.L0CompactionConcurrency)
12731271
}
12741272
// compactionDebt >= ccSignal2 then can run another compaction, where
@@ -1378,7 +1376,7 @@ func (p *compactionPickerByScore) pickAutoScore(env compactionEnv) (pc *pickedCo
13781376
}
13791377

13801378
if info.level == 0 {
1381-
pc = pickL0(env, p.opts, p.vers, p.l0Organizer, p.baseLevel)
1379+
pc = pickL0(env, p.opts, p.vers, p.latestVersionState.l0Organizer, p.baseLevel)
13821380
// Fail-safe to protect against compacting the same sstable
13831381
// concurrently.
13841382
if pc != nil && !inputRangeAlreadyCompacting(env, pc) {
@@ -1394,12 +1392,12 @@ func (p *compactionPickerByScore) pickAutoScore(env compactionEnv) (pc *pickedCo
13941392

13951393
// info.level > 0
13961394
var ok bool
1397-
info.file, ok = pickCompactionSeedFile(p.vers, p.virtualBackings, p.opts, info.level, info.outputLevel, env.earliestSnapshotSeqNum, env.problemSpans)
1395+
info.file, ok = pickCompactionSeedFile(p.vers, &p.latestVersionState.virtualBackings, p.opts, info.level, info.outputLevel, env.earliestSnapshotSeqNum, env.problemSpans)
13981396
if !ok {
13991397
continue
14001398
}
14011399

1402-
pc := pickAutoLPositive(env, p.opts, p.vers, p.l0Organizer, *info, p.baseLevel)
1400+
pc := pickAutoLPositive(env, p.opts, p.vers, p.latestVersionState.l0Organizer, *info, p.baseLevel)
14031401
// Fail-safe to protect against compacting the same sstable concurrently.
14041402
if pc != nil && !inputRangeAlreadyCompacting(env, pc) {
14051403
p.addScoresToPickedCompactionMetrics(pc, scores)
@@ -1583,7 +1581,8 @@ func (p *compactionPickerByScore) pickedCompactionFromCandidateFile(
15831581
}
15841582
}
15851583

1586-
pc := newPickedCompaction(p.opts, p.vers, p.l0Organizer, startLevel, outputLevel, p.baseLevel)
1584+
pc := newPickedCompaction(p.opts, p.vers, p.latestVersionState.l0Organizer,
1585+
startLevel, outputLevel, p.baseLevel)
15871586
pc.kind = kind
15881587
pc.startLevel.files = inputs
15891588
pc.smallest, pc.largest = manifest.KeyRange(pc.cmp, pc.startLevel.files.All())
@@ -2030,7 +2029,8 @@ func pickReadTriggeredCompactionHelper(
20302029
return nil
20312030
}
20322031

2033-
pc = newPickedCompaction(p.opts, p.vers, p.l0Organizer, rc.level, defaultOutputLevel(rc.level, p.baseLevel), p.baseLevel)
2032+
pc = newPickedCompaction(p.opts, p.vers, p.latestVersionState.l0Organizer,
2033+
rc.level, defaultOutputLevel(rc.level, p.baseLevel), p.baseLevel)
20342034

20352035
pc.startLevel.files = overlapSlice
20362036
if !pc.setupInputs(p.opts, env.diskAvailBytes, pc.startLevel, env.problemSpans) {

0 commit comments

Comments
 (0)