From c51ba69c09051acdbd1dec034d69f74c3041db4c Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Wed, 30 Sep 2020 08:39:46 -0600 Subject: [PATCH] Fix RBF sync calls --- rbf/db.go | 5 +++++ rbf/rbf.go | 16 ++++++++++++++++ rbf/wal.go | 6 +++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/rbf/db.go b/rbf/db.go index 737d7793b..9ff40a204 100644 --- a/rbf/db.go +++ b/rbf/db.go @@ -294,6 +294,11 @@ func (db *DB) checkpoint(exclusive bool, mu sync.Locker) error { } } + // Ensure WAL pages are fully copied & synced to DB file. + if err := db.file.Sync(); err != nil { + return fmt.Errorf("db file sync: %w", err) + } + // Remove WAL segments that have been checkpointed. if maxCheckpointedWALID != 0 { for _, segment := range segments { diff --git a/rbf/rbf.go b/rbf/rbf.go index f152e3499..a512fe237 100644 --- a/rbf/rbf.go +++ b/rbf/rbf.go @@ -648,3 +648,19 @@ func RowValues(b []uint64) []uint64 { // _, file, line, _ := runtime.Caller(skip + 1) // return fmt.Sprintf("%s:%d", file, line) // } + +// truncate truncates the file at path to sz bytes. File must exist. +func truncate(path string, sz int64) error { + f, err := os.OpenFile(path, os.O_WRONLY, 0666) + if err != nil { + return fmt.Errorf("open file: %w", err) + } + defer f.Close() + + if err := f.Truncate(sz); err != nil { + return fmt.Errorf("truncate: %w", err) + } else if err := f.Sync(); err != nil { + return fmt.Errorf("sync: %w", err) + } + return f.Close() +} diff --git a/rbf/wal.go b/rbf/wal.go index bb9b53157..14e64a107 100644 --- a/rbf/wal.go +++ b/rbf/wal.go @@ -74,8 +74,8 @@ func (s *WALSegment) Open() (err error) { s.PageN = int(sz / PageSize) if sz%PageSize != 0 { sz = int64(s.PageN * PageSize) - if err := os.Truncate(s.Path, sz); err != nil { - return fmt.Errorf("truncate wal segment file: %w", err) + if err := truncate(s.Path, sz); err != nil { + return fmt.Errorf("truncate wal file: %w", err) } } @@ -229,7 +229,7 @@ func truncateWALAfter(segments []WALSegment, walID int64) ([]WALSegment, error) newSegment := *segment newSegment.PageN = int((walID - newSegment.MinWALID) + 1) - if err := os.Truncate(newSegment.Path, int64(newSegment.PageN)*PageSize); err != nil { + if err := truncate(newSegment.Path, int64(newSegment.PageN)*PageSize); err != nil { return segments, err } newSegments = append(newSegments, newSegment)