Skip to content

Commit 1d823f7

Browse files
authored
*: future-proof DropDB (#903)
When adding an index directory, we didn't account for it in DropDB, causing os.Remove to error with "directory is not empty". This commit simply iterates over all directory entries in the storage path and renames them, rather than only renaming a pre-specified subset. Additionally, Remove has been changed to RemoveAll in DropDB, which handles directories with elements still in them.
1 parent bfdd9ec commit 1d823f7

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

db.go

+32-18
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ func (s *ColumnStore) DropDB(name string) error {
643643
s.mtx.Lock()
644644
defer s.mtx.Unlock()
645645
delete(s.dbs, name)
646-
return os.Remove(filepath.Join(s.DatabasesDir(), name))
646+
return os.RemoveAll(filepath.Join(s.DatabasesDir(), name))
647647
}
648648

649649
func (db *DB) openWAL(ctx context.Context, opts ...wal.TestingOption) (WAL, error) {
@@ -668,6 +668,8 @@ func (db *DB) openWAL(ctx context.Context, opts ...wal.TestingOption) (WAL, erro
668668
const (
669669
walPath = "wal"
670670
snapshotsPath = "snapshots"
671+
indexPath = "index"
672+
trashPath = "trash"
671673
)
672674

673675
func (db *DB) walDir() string {
@@ -679,11 +681,11 @@ func (db *DB) snapshotsDir() string {
679681
}
680682

681683
func (db *DB) trashDir() string {
682-
return filepath.Join(db.storagePath, "trash")
684+
return filepath.Join(db.storagePath, trashPath)
683685
}
684686

685687
func (db *DB) indexDir() string {
686-
return filepath.Join(db.storagePath, "index")
688+
return filepath.Join(db.storagePath, indexPath)
687689
}
688690

689691
// recover attempts to recover database state from a combination of snapshots and the WAL.
@@ -1319,10 +1321,22 @@ func validateName(name string) bool {
13191321
return !strings.Contains(name, "/")
13201322
}
13211323

1322-
// dropStorage removes snapshots and WAL data from the storage directory.
1324+
// dropStorage removes all data from the storage directory, but leaves the empty
1325+
// storage directory.
13231326
func (db *DB) dropStorage() error {
13241327
trashDir := db.trashDir()
13251328

1329+
entries, err := os.ReadDir(db.storagePath)
1330+
if err != nil {
1331+
if os.IsNotExist(err) {
1332+
// Nothing to drop.
1333+
return nil
1334+
}
1335+
return err
1336+
}
1337+
// Try to rename all entries as this is O(1) per entry. We want to preserve
1338+
// the storagePath for future opens of this database. Callers that want to
1339+
// drop the DB remove storagePath themselves.
13261340
if moveErr := func() error {
13271341
if err := os.MkdirAll(trashDir, os.FileMode(0o755)); err != nil {
13281342
return fmt.Errorf("making trash dir: %w", err)
@@ -1334,23 +1348,23 @@ func (db *DB) dropStorage() error {
13341348
if err != nil {
13351349
return err
13361350
}
1337-
if err := os.Rename(db.snapshotsDir(), filepath.Join(tmpPath, snapshotsPath)); err != nil && !os.IsNotExist(err) {
1338-
return err
1339-
}
1340-
if err := os.Rename(db.walDir(), filepath.Join(tmpPath, walPath)); err != nil && !os.IsNotExist(err) {
1341-
return err
1351+
errs := make([]error, 0, len(entries))
1352+
for _, e := range entries {
1353+
if err := os.Rename(filepath.Join(db.storagePath, e.Name()), filepath.Join(tmpPath, e.Name())); err != nil && !os.IsNotExist(err) {
1354+
errs = append(errs, err)
1355+
}
13421356
}
1343-
return nil
1357+
return errors.Join(errs...)
13441358
}(); moveErr != nil {
1345-
// If we failed to move the wal/snapshots to the trash dir, fall
1346-
// back to attempting to remove them with RemoveAll.
1347-
if err := os.RemoveAll(db.snapshotsDir()); err != nil {
1348-
return fmt.Errorf("%v: %v", moveErr, err)
1349-
}
1350-
if err := os.RemoveAll(db.walDir()); err != nil {
1351-
return fmt.Errorf("%v: %v", moveErr, err)
1359+
// If we failed to move storage path entries to the trash dir, fall back
1360+
// to attempting to remove them with RemoveAll.
1361+
errs := make([]error, 0, len(entries))
1362+
for _, e := range entries {
1363+
if err := os.RemoveAll(filepath.Join(db.storagePath, e.Name())); err != nil {
1364+
errs = append(errs, err)
1365+
}
13521366
}
1353-
return moveErr
1367+
return errors.Join(errs...)
13541368
}
13551369
return os.RemoveAll(trashDir)
13561370
}

0 commit comments

Comments
 (0)