@@ -102,18 +102,7 @@ func Open(dirname string, opts *Options) (db *DB, err error) {
102102 }
103103 }
104104
105- // Open the database and WAL directories first.
106- dirs , err := prepareOpenAndLockDirs (dirname , opts )
107- if err != nil {
108- err = errors .Wrapf (err , "error opening database at %q" , dirname )
109- err = errors .CombineErrors (err , dirs .Close ())
110- return nil , err
111- }
112- // Locks in RecoveryDirLocks can be closed as soon as we've finished opening
113- // the database.
114- defer func () { _ = dirs .RecoveryDirLocks .Close () }()
115- defer maybeCleanUp (dirs .Close )
116-
105+ // Recover the current database state.
117106 rs , err := recoverState (opts , dirname )
118107 if err != nil {
119108 return nil , err
@@ -149,7 +138,7 @@ func Open(dirname string, opts *Options) (db *DB, err error) {
149138 }
150139
151140 if ! opts .ReadOnly {
152- if err := rs .RemoveObsolete (); err != nil {
141+ if err := rs .RemoveObsolete (opts ); err != nil {
153142 return nil , err
154143 }
155144 }
@@ -169,7 +158,7 @@ func Open(dirname string, opts *Options) (db *DB, err error) {
169158 split : opts .Comparer .Split ,
170159 abbreviatedKey : opts .Comparer .AbbreviatedKey ,
171160 largeBatchThreshold : (opts .MemTableSize - uint64 (memTableEmptySize )) / 2 ,
172- dirs : dirs ,
161+ dirs : rs . dirs ,
173162 objProvider : rs .objProvider ,
174163 closed : new (atomic.Value ),
175164 closedCh : make (chan struct {}),
@@ -297,8 +286,8 @@ func Open(dirname string, opts *Options) (db *DB, err error) {
297286 })
298287
299288 walOpts := wal.Options {
300- Primary : dirs .WALPrimary ,
301- Secondary : dirs .WALSecondary ,
289+ Primary : rs . dirs .WALPrimary ,
290+ Secondary : rs . dirs .WALSecondary ,
302291 MinUnflushedWALNum : wal .NumWAL (d .mu .versions .minUnflushedLogNum ),
303292 MaxNumRecyclableLogs : opts .MemTableStopWritesThreshold + 1 ,
304293 NoSyncOnClose : opts .NoSyncOnClose ,
@@ -323,45 +312,7 @@ func Open(dirname string, opts *Options) (db *DB, err error) {
323312 return nil , err
324313 }
325314
326- // Remove obsolete WAL files now (as opposed to relying on asynchronous
327- // cleanup) to prevent crash loops due to no disk space (ENOSPC).
328- var retainedWALs wal.Logs
329- for _ , w := range wals {
330- // Any WALs with file numbers ≥ minUnflushedLogNum must be replayed to
331- // recover the state.
332- if base .DiskFileNum (w .Num ) >= d .mu .versions .minUnflushedLogNum {
333- retainedWALs = append (retainedWALs , w )
334- continue
335- }
336- // Skip removal of obsolete WALs in read-only mode.
337- if opts .ReadOnly {
338- continue
339- }
340- // Remove obsolete WALs, logging each removal.
341- for i := range w .NumSegments () {
342- fs , path := w .SegmentLocation (i )
343- if err := fs .Remove (path ); err != nil {
344- // It's not a big deal if we can't delete the file now.
345- // We'll try to remove it later in the cleanup process.
346- d .opts .EventListener .WALDeleted (WALDeleteInfo {
347- JobID : 0 ,
348- Path : path ,
349- FileNum : base .DiskFileNum (w .Num ),
350- Err : err ,
351- })
352- retainedWALs = append (retainedWALs , w )
353- } else {
354- d .opts .EventListener .WALDeleted (WALDeleteInfo {
355- JobID : 0 ,
356- Path : path ,
357- FileNum : base .DiskFileNum (w .Num ),
358- Err : nil ,
359- })
360- }
361- }
362- }
363-
364- walManager , err := wal .Init (walOpts , retainedWALs )
315+ walManager , err := wal .Init (walOpts , rs .walsReplay )
365316 if err != nil {
366317 return nil , err
367318 }
@@ -536,6 +487,12 @@ func Open(dirname string, opts *Options) (db *DB, err error) {
536487 d .maybeScheduleFlush ()
537488 d .maybeScheduleCompaction ()
538489
490+ // Locks in RecoveryDirLocks can be closed as soon as we've finished opening
491+ // the database.
492+ if err = rs .dirs .RecoveryDirLocks .Close (); err != nil {
493+ return nil , err
494+ }
495+
539496 // Note: this is a no-op if invariants are disabled or race is enabled.
540497 //
541498 // Setting a finalizer on *DB causes *DB to never be reclaimed and the
0 commit comments