From 41af39f31f85f2856e3358aa4d530e9291bc2841 Mon Sep 17 00:00:00 2001 From: ZRHann Date: Thu, 18 Jun 2026 13:46:59 +0800 Subject: [PATCH] metadata: set NoFreelistSync on bolt databases to avoid write amplification bbolt rewrites the entire freelist on every transaction commit. Once a metadata database accumulates many free pages (for example after GC frees most of a large database), each small metadata write amplifies into a multi-MB disk write. With a high commit rate this can saturate disk write bandwidth and, because every commit holds bbolt's single writer lock while fsyncing, stall otherwise-cheap build operations. Set NoFreelistSync on the bolt databases that buildkit opens itself (containerdmeta.db, metadata_v2.db and cache.db). The freelist is not data; it is reconstructed by scanning the database on open, so durability is unaffected. containerd applies the same option to its own metadata database for the same reason: https://github.com/containerd/containerd/pull/6761 Signed-off-by: ZRHann --- cache/metadata/metadata.go | 2 +- solver/bboltcachestorage/storage.go | 3 ++- worker/runc/runc.go | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cache/metadata/metadata.go b/cache/metadata/metadata.go index 7eb9c4aad6d2..addcf81eb3ce 100644 --- a/cache/metadata/metadata.go +++ b/cache/metadata/metadata.go @@ -41,7 +41,7 @@ func NewStore(dbPath string) (*Store, error) { ) } } - db, err := boltutil.Open(dbPath, 0600, nil) + db, err := boltutil.Open(dbPath, 0600, &bolt.Options{NoFreelistSync: true}) if err != nil { return nil, errors.Wrapf(err, "failed to open database file %s", dbPath) } diff --git a/solver/bboltcachestorage/storage.go b/solver/bboltcachestorage/storage.go index dc9cd84b8aa6..585917a5ea5a 100644 --- a/solver/bboltcachestorage/storage.go +++ b/solver/bboltcachestorage/storage.go @@ -26,7 +26,8 @@ type Store struct { func NewStore(dbPath string) (*Store, error) { db, err := boltutil.SafeOpen(dbPath, 0600, &bolt.Options{ - NoSync: true, + NoSync: true, + NoFreelistSync: true, }) if err != nil { return nil, err diff --git a/worker/runc/runc.go b/worker/runc/runc.go index 4441060f4f26..3397b110e9d9 100644 --- a/worker/runc/runc.go +++ b/worker/runc/runc.go @@ -95,7 +95,9 @@ func NewWorkerOpt(root string, snFactory SnapshotterFactory, rootless bool, proc return opt, err } - db, err := bolt.Open(filepath.Join(root, "containerdmeta.db"), 0644, nil) + db, err := bolt.Open(filepath.Join(root, "containerdmeta.db"), 0644, &bolt.Options{ + NoFreelistSync: true, + }) if err != nil { return opt, err }