Skip to content

Commit f4e77d2

Browse files
authored
Merge pull request #20 from useblacksmith/sync-bbolt-on-close
boltutil: sync bbolt databases on close to prevent corruption
2 parents aacc478 + 55d37dc commit f4e77d2

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

util/db/boltutil/db.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,40 @@ package boltutil
22

33
import (
44
"io/fs"
5+
"sync"
56

7+
"github.com/moby/buildkit/util/bklog"
68
"github.com/moby/buildkit/util/db"
79
bolt "go.etcd.io/bbolt"
810
)
911

12+
// syncingDB wraps a bolt.DB to ensure data is synced to disk before closing.
13+
// This is important when using NoSync mode, as otherwise dirty pages may not
14+
// be flushed to disk before unmount, leading to corruption on network block
15+
// devices or when taking filesystem snapshots.
16+
type syncingDB struct {
17+
*bolt.DB
18+
closeOnce sync.Once
19+
closeErr error
20+
}
21+
22+
// Close syncs the database to disk before closing.
23+
// This ensures all pending writes are flushed even when NoSync is enabled,
24+
// preventing corruption during graceful shutdown. Safe to call multiple times.
25+
func (s *syncingDB) Close() error {
26+
s.closeOnce.Do(func() {
27+
if err := s.Sync(); err != nil {
28+
bklog.L.Warnf("failed to sync database before close: %v", err)
29+
}
30+
s.closeErr = s.DB.Close()
31+
})
32+
return s.closeErr
33+
}
34+
1035
func Open(p string, mode fs.FileMode, options *bolt.Options) (db.DB, error) {
1136
bdb, err := bolt.Open(p, mode, options)
1237
if err != nil {
1338
return nil, err
1439
}
15-
return bdb, nil
40+
return &syncingDB{DB: bdb}, nil
1641
}

0 commit comments

Comments
 (0)