diff --git a/rbf/cfg/cfg.go b/rbf/cfg/cfg.go index 2b65a2b2b..725646ec8 100644 --- a/rbf/cfg/cfg.go +++ b/rbf/cfg/cfg.go @@ -28,7 +28,8 @@ type Config struct { MaxWALCheckpointSize int64 `toml:"max-wal-checkpoint-size"` // Set before calling db.Open() - FsyncEnabled bool `toml:"fsync"` + FsyncEnabled bool `toml:"fsync"` + FsyncWALEnabled bool `toml:"fsync-wal"` // for mmap correctness testing. DoAllocZero bool `toml:"do-alloc-zero"` @@ -53,6 +54,7 @@ func NewDefaultConfig() *Config { MinWALCheckpointSize: DefaultMinWALCheckpointSize, MaxWALCheckpointSize: DefaultMaxWALCheckpointSize, FsyncEnabled: true, + FsyncWALEnabled: true, MaxDelete: DefaultMaxDelete, // CI passed with 20. 50 was too big for CI, even on X-large instances. @@ -70,5 +72,6 @@ func (cfg *Config) DefineFlags(flags *pflag.FlagSet) { // renamed from --rbf-fsync to just --fsync because now it applies to all Tx backends. flags.BoolVar(&cfg.FsyncEnabled, "fsync", default0.FsyncEnabled, "enable fsync fully safe flush-to-disk") + flags.BoolVar(&cfg.FsyncWALEnabled, "fsync-wal", default0.FsyncWALEnabled, "enable fsync on write-ahead log") flags.Int64Var(&cfg.CursorCacheSize, "rbf.cursor-cache-size", default0.CursorCacheSize, "how big a Cursor arena to maintain. 0 means use sync.Pool with dynamic sizing. Note that <= 20 is needed to pass CI. Controls the memory footprint of rbf.") } diff --git a/rbf/rbf.go b/rbf/rbf.go index ac156a2c7..2778a6592 100644 --- a/rbf/rbf.go +++ b/rbf/rbf.go @@ -755,6 +755,13 @@ func (db *DB) fsync(f *os.File) error { return f.Sync() } +func (db *DB) fsyncWAL(f *os.File) error { + if !db.cfg.FsyncEnabled || !db.cfg.FsyncWALEnabled { + return nil // no sync if either fsync flag is disabled + } + return f.Sync() +} + // uint32Hasher implements Hasher for uint32 keys. type uint32Hasher struct{} diff --git a/rbf/tx.go b/rbf/tx.go index 98d0019d9..24897b2f7 100644 --- a/rbf/tx.go +++ b/rbf/tx.go @@ -1900,7 +1900,7 @@ func (tx *Tx) flush() error { // Flush & sync WAL. if err := w.Flush(); err != nil { return fmt.Errorf("flush wal: %w", err) - } else if err := tx.db.fsync(tx.db.walFile); err != nil { + } else if err := tx.db.fsyncWAL(tx.db.walFile); err != nil { return fmt.Errorf("sync wal: %w", err) }