From 5ce378b046e500eadd1fb53e1b1488488488ce1f Mon Sep 17 00:00:00 2001 From: Tommi Virtanen Date: Sat, 22 Mar 2014 20:45:53 -0700 Subject: Call fdatasync/fsync after writing out non-meta pages This avoids a case where writes can be reordered so meta page is written before a page it refers to, potentially causing a corrupt database after a power loss or kernel crash. --- sync_linux.go | 10 ++++++++++ sync_std.go | 10 ++++++++++ tx.go | 3 +++ 3 files changed, 23 insertions(+) create mode 100644 sync_linux.go create mode 100644 sync_std.go diff --git a/sync_linux.go b/sync_linux.go new file mode 100644 index 0000000..351b65a --- /dev/null +++ b/sync_linux.go @@ -0,0 +1,10 @@ +package bolt + +import ( + "os" + "syscall" +) + +func fdatasync(f *os.File) error { + return syscall.Fdatasync(int(f.Fd())) +} diff --git a/sync_std.go b/sync_std.go new file mode 100644 index 0000000..d858b23 --- /dev/null +++ b/sync_std.go @@ -0,0 +1,10 @@ +// +build !linux + +package bolt + +import "os" + +// Fall back to syncing metadata too. +func fdatasync(f *os.File) error { + return f.Sync() +} diff --git a/tx.go b/tx.go index 5b2b14d..181444e 100644 --- a/tx.go +++ b/tx.go @@ -329,6 +329,9 @@ func (t *Tx) write() error { return err } } + if err := fdatasync(t.db.file); err != nil { + return err + } // Clear out page cache. t.pages = make(map[pgid]*page) -- cgit v1.2.3 From a10ce47f54a5c57292d11faec14e398f11b7ae4f Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Sun, 23 Mar 2014 08:59:45 -0700 Subject: Consolidate syscall files. --- sync_linux.go | 10 ---------- sync_std.go | 10 ---------- syscall.go | 9 +++++++++ syscall_linux.go | 10 ++++++++++ 4 files changed, 19 insertions(+), 20 deletions(-) delete mode 100644 sync_linux.go delete mode 100644 sync_std.go create mode 100644 syscall.go create mode 100644 syscall_linux.go diff --git a/sync_linux.go b/sync_linux.go deleted file mode 100644 index 351b65a..0000000 --- a/sync_linux.go +++ /dev/null @@ -1,10 +0,0 @@ -package bolt - -import ( - "os" - "syscall" -) - -func fdatasync(f *os.File) error { - return syscall.Fdatasync(int(f.Fd())) -} diff --git a/sync_std.go b/sync_std.go deleted file mode 100644 index d858b23..0000000 --- a/sync_std.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !linux - -package bolt - -import "os" - -// Fall back to syncing metadata too. -func fdatasync(f *os.File) error { - return f.Sync() -} diff --git a/syscall.go b/syscall.go new file mode 100644 index 0000000..c3a1bb5 --- /dev/null +++ b/syscall.go @@ -0,0 +1,9 @@ +// +build !linux + +package bolt + +import "os" + +func fdatasync(f *os.File) error { + return f.Sync() +} diff --git a/syscall_linux.go b/syscall_linux.go new file mode 100644 index 0000000..351b65a --- /dev/null +++ b/syscall_linux.go @@ -0,0 +1,10 @@ +package bolt + +import ( + "os" + "syscall" +) + +func fdatasync(f *os.File) error { + return syscall.Fdatasync(int(f.Fd())) +} -- cgit v1.2.3