Skip to content

Add no_sync option to mount manager and erofs snapshotter bolt DBs#13143

Draft
djs55 wants to merge 1 commit intocontainerd:mainfrom
djs55:nosync-mount-erofs
Draft

Add no_sync option to mount manager and erofs snapshotter bolt DBs#13143
djs55 wants to merge 1 commit intocontainerd:mainfrom
djs55:nosync-mount-erofs

Conversation

@djs55
Copy link
Copy Markdown

@djs55 djs55 commented Mar 31, 2026

The metadata plugin already exposes a no_sync option (PR #10745) that disables F_FULLFSYNC on its bolt DB. This extends the same pattern to two more bolt databases: the mount manager (mounts.db) and the erofs snapshotter (metadata.db).

On macOS, F_FULLFSYNC costs ~8ms per bolt transaction, particularly affecting nerdbox, see this benchmark (Apple M-series, bbolt v1.4.3):

mkdir /tmp/test
cat > /tmp/test/main.go <<EOT
    package main
    import (
        "fmt"; "os"; "path/filepath"; "time"
        bolt "go.etcd.io/bbolt"
    )
    func bench(label string, noSync bool) {
        dir, _ := os.MkdirTemp("", "bolt-*")
        defer os.RemoveAll(dir)
        db, _ := bolt.Open(filepath.Join(dir, "t.db"), 0600,
            &bolt.Options{NoSync: noSync, NoGrowSync: noSync})
        defer db.Close()
        db.Update(func(tx *bolt.Tx) error { _, e := tx.CreateBucket([]byte("b")); return e })
        const N = 200
        start := time.Now()
        for i := range N {
            db.Update(func(tx *bolt.Tx) error {
                return tx.Bucket([]byte("b")).Put([]byte(fmt.Sprintf("k%d", i)), []byte("v"))
            })
        }
        d := time.Since(start)
        fmt.Printf("%-10s %d writes in %v (%.0f ops/s, %.2f ms/op)\n",
            label, N, d.Round(time.Millisecond), float64(N)/d.Seconds(), float64(d.Milliseconds())/float64(N))
    }
    func main() { bench("sync:", false); bench("no_sync:", true) }
EOT
cd /tmp/test
go mod init test
go mod tidy
go run main.go

Results:

    sync:      200 writes in 1.605s (125 ops/s, 8.03 ms/op)
    no_sync:   200 writes in 3ms (74203 ops/s, 0.01 ms/op)

Configuration:

    [plugins.'io.containerd.mount-manager.v1.bolt']
      no_sync = true

    [plugins.'io.containerd.snapshotter.v1.erofs']
      no_sync = true

The metadata plugin already exposes a no_sync option (PR containerd#10745) that
disables F_FULLFSYNC on its bolt DB. This extends the same pattern to
two more bolt databases: the mount manager (mounts.db) and the erofs
snapshotter (metadata.db).

On macOS, F_FULLFSYNC costs ~8ms per bolt transaction, particularly
affecting nerdbox, see this benchmark (Apple M-series, bbolt v1.4.3):

```
mkdir /tmp/test
cat > /tmp/test/main.go <<EOT
    package main
    import (
        "fmt"; "os"; "path/filepath"; "time"
        bolt "go.etcd.io/bbolt"
    )
    func bench(label string, noSync bool) {
        dir, _ := os.MkdirTemp("", "bolt-*")
        defer os.RemoveAll(dir)
        db, _ := bolt.Open(filepath.Join(dir, "t.db"), 0600,
            &bolt.Options{NoSync: noSync, NoGrowSync: noSync})
        defer db.Close()
        db.Update(func(tx *bolt.Tx) error { _, e := tx.CreateBucket([]byte("b")); return e })
        const N = 200
        start := time.Now()
        for i := range N {
            db.Update(func(tx *bolt.Tx) error {
                return tx.Bucket([]byte("b")).Put([]byte(fmt.Sprintf("k%d", i)), []byte("v"))
            })
        }
        d := time.Since(start)
        fmt.Printf("%-10s %d writes in %v (%.0f ops/s, %.2f ms/op)\n",
            label, N, d.Round(time.Millisecond), float64(N)/d.Seconds(), float64(d.Milliseconds())/float64(N))
    }
    func main() { bench("sync:", false); bench("no_sync:", true) }
EOT
cd /tmp/test
go mod init test
go mod tidy
go run main.go
```

Results:

```
    sync:      200 writes in 1.605s (125 ops/s, 8.03 ms/op)
    no_sync:   200 writes in 3ms (74203 ops/s, 0.01 ms/op)
```

Configuration:

```
    [plugins.'io.containerd.mount-manager.v1.bolt']
      no_sync = true

    [plugins.'io.containerd.snapshotter.v1.erofs']
      no_sync = true
```

Signed-off-by: David Scott <dave@recoil.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

2 participants