@@ -1100,10 +1100,10 @@ func (d *DB) clearCompactingState(c *compaction, rollback bool) {
11001100 // It is a bit peculiar that we are fiddling with th current version state
11011101 // in a separate critical section from when this version was installed.
11021102 // But this fiddling is necessary if the compaction failed. When the
1103- // compaction succeeded, we've already done this in logAndApply , so this
1104- // seems redundant. Anyway, we clear the pickedCompactionCache since we
1103+ // compaction succeeded, we've already done this in UpdateVersionLocked , so
1104+ // this seems redundant. Anyway, we clear the pickedCompactionCache since we
11051105 // may be able to pick a better compaction (though when this compaction
1106- // succeeded we've also cleared the cache in logAndApply ).
1106+ // succeeded we've also cleared the cache in UpdateVersionLocked ).
11071107 defer d .mu .versions .logUnlockAndInvalidatePickedCompactionCache ()
11081108 d .mu .versions .l0Organizer .InitCompactingFileInfo (l0InProgress )
11091109 }()
@@ -1467,44 +1467,38 @@ func (d *DB) flush1() (bytesFlushed uint64, err error) {
14671467 d .addInProgressCompaction (c )
14681468
14691469 jobID := d .newJobIDLocked ()
1470- d . opts . EventListener . FlushBegin ( FlushInfo {
1470+ info := FlushInfo {
14711471 JobID : int (jobID ),
14721472 Input : inputs ,
14731473 InputBytes : inputBytes ,
14741474 Ingest : ingest ,
1475- })
1475+ }
1476+ d .opts .EventListener .FlushBegin (info )
1477+
14761478 startTime := d .timeNow ()
14771479
14781480 var ve * manifest.VersionEdit
14791481 var stats compact.Stats
14801482 // To determine the target level of the files in the ingestedFlushable, we
1481- // need to acquire the logLock, and not release it for that duration. Since,
1482- // we need to acquire the logLock below to perform the logAndApply step
1483- // anyway, we create the VersionEdit for ingestedFlushable outside of
1484- // runCompaction. For all other flush cases, we construct the VersionEdit
1485- // inside runCompaction.
1483+ // need to acquire the logLock, and not release it for that duration. Since
1484+ // UpdateVersionLocked acquires it anyway, we create the VersionEdit for
1485+ // ingestedFlushable outside runCompaction. For all other flush cases, we
1486+ // construct the VersionEdit inside runCompaction.
1487+ var compactionErr error
14861488 if c .kind != compactionKindIngestedFlushable {
1487- ve , stats , err = d .runCompaction (jobID , c )
1489+ ve , stats , compactionErr = d .runCompaction (jobID , c )
14881490 }
14891491
1490- // Acquire logLock. This will be released either on an error, by way of
1491- // logUnlock, or through a call to logAndApply if there is no error.
1492- d .mu .versions .logLock ()
1493-
1494- if c .kind == compactionKindIngestedFlushable {
1495- ve , err = d .runIngestFlush (c )
1496- }
1492+ err = d .mu .versions .UpdateVersionLocked (func () (versionUpdate , error ) {
1493+ err := compactionErr
1494+ if c .kind == compactionKindIngestedFlushable {
1495+ ve , err = d .runIngestFlush (c )
1496+ }
1497+ info .Duration = d .timeNow ().Sub (startTime )
1498+ if err != nil {
1499+ return versionUpdate {}, err
1500+ }
14971501
1498- info := FlushInfo {
1499- JobID : int (jobID ),
1500- Input : inputs ,
1501- InputBytes : inputBytes ,
1502- Duration : d .timeNow ().Sub (startTime ),
1503- Done : true ,
1504- Ingest : ingest ,
1505- Err : err ,
1506- }
1507- if err == nil {
15081502 validateVersionEdit (ve , d .opts .Comparer .ValidateKey , d .opts .Comparer .FormatKey , d .opts .Logger )
15091503 for i := range ve .NewTables {
15101504 e := & ve .NewTables [i ]
@@ -1515,9 +1509,6 @@ func (d *DB) flush1() (bytesFlushed uint64, err error) {
15151509 info .IngestLevels = append (info .IngestLevels , e .Level )
15161510 }
15171511 }
1518- if len (ve .NewTables ) == 0 {
1519- info .Err = errEmptyTable
1520- }
15211512
15221513 // The flush succeeded or it produced an empty sstable. In either case we
15231514 // want to bump the minimum unflushed log number to the log number of the
@@ -1550,7 +1541,6 @@ func (d *DB) flush1() (bytesFlushed uint64, err error) {
15501541 // write a file overlapping with the excise span.
15511542 if ingestFlushable .exciseSpan .OverlapsInternalKeyRange (d .cmp , c2 .smallest , c2 .largest ) {
15521543 c2 .cancel .Store (true )
1553- continue
15541544 }
15551545 }
15561546
@@ -1570,17 +1560,13 @@ func (d *DB) flush1() (bytesFlushed uint64, err error) {
15701560 }
15711561 }
15721562 }
1573- err = d .mu .versions .logAndApply (jobID , ve , & c .metrics , false , /* forceRotation */
1574- func () []compactionInfo { return d .getInProgressCompactionInfoLocked (c ) })
1575- if err != nil {
1576- info .Err = err
1577- }
1578- } else {
1579- // We won't be performing the logAndApply step because of the error, so
1580- // logUnlock. We don't need to invalidate the pickedCompactionCache since
1581- // the flush failed and so the latest version has not changed.
1582- d .mu .versions .logUnlock ()
1583- }
1563+ return versionUpdate {
1564+ VE : ve ,
1565+ JobID : jobID ,
1566+ Metrics : c .metrics ,
1567+ InProgressCompactionsFn : func () []compactionInfo { return d .getInProgressCompactionInfoLocked (c ) },
1568+ }, nil
1569+ })
15841570
15851571 // If err != nil, then the flush will be retried, and we will recalculate
15861572 // these metrics.
@@ -1610,11 +1596,15 @@ func (d *DB) flush1() (bytesFlushed uint64, err error) {
16101596 }
16111597 }
16121598 d .maybeTransitionSnapshotsToFileOnlyLocked ()
1613-
16141599 }
16151600 // Signal FlushEnd after installing the new readState. This helps for unit
16161601 // tests that use the callback to trigger a read using an iterator with
16171602 // IterOptions.OnlyReadGuaranteedDurable.
1603+ info .Err = err
1604+ if info .Err == nil && len (ve .NewTables ) == 0 {
1605+ info .Err = errEmptyTable
1606+ }
1607+ info .Done = true
16181608 info .TotalDuration = d .timeNow ().Sub (startTime )
16191609 d .opts .EventListener .FlushEnd (info )
16201610
@@ -2468,9 +2458,7 @@ func (d *DB) compact1(c *compaction, errChannel chan error) (err error) {
24682458 info .Duration = d .timeNow ().Sub (startTime )
24692459 if err == nil {
24702460 validateVersionEdit (ve , d .opts .Comparer .ValidateKey , d .opts .Comparer .FormatKey , d .opts .Logger )
2471- err = func () error {
2472- var err error
2473- d .mu .versions .logLock ()
2461+ err = d .mu .versions .UpdateVersionLocked (func () (versionUpdate , error ) {
24742462 // Check if this compaction had a conflicting operation (eg. a d.excise())
24752463 // that necessitates it restarting from scratch. Note that since we hold
24762464 // the manifest lock, we don't expect this bool to change its value
@@ -2485,17 +2473,18 @@ func (d *DB) compact1(c *compaction, errChannel chan error) (err error) {
24852473 // would not have been true). We should delete any tables already
24862474 // created, as d.runCompaction did not do that.
24872475 d .cleanupVersionEdit (ve )
2488- // logAndApply calls logUnlock. If we didn't call it, we need to call
2489- // logUnlock ourselves. We also invalidate the pickedCompactionCache
2490- // since this failed compaction may be the highest priority to run
2491- // next.
2492- d .mu .versions .logUnlockAndInvalidatePickedCompactionCache ()
2493- return err
2476+ // Note that UpdateVersionLocked invalidates the pickedCompactionCache
2477+ // when we return, which is relevant because this failed compaction
2478+ // may be the highest priority to run next.
2479+ return versionUpdate {}, err
24942480 }
2495- return d .mu .versions .logAndApply (jobID , ve , & c .metrics , false /* forceRotation */ , func () []compactionInfo {
2496- return d .getInProgressCompactionInfoLocked (c )
2497- })
2498- }()
2481+ return versionUpdate {
2482+ VE : ve ,
2483+ JobID : jobID ,
2484+ Metrics : c .metrics ,
2485+ InProgressCompactionsFn : func () []compactionInfo { return d .getInProgressCompactionInfoLocked (c ) },
2486+ }, nil
2487+ })
24992488 }
25002489
25012490 info .Done = true
0 commit comments