mirror of https://github.com/etcd-io/bbolt.git
commit
d285804df1
|
@ -1,13 +1,12 @@
|
||||||
package bolt
|
package bolt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
var odirect = syscall.O_DIRECT
|
var odirect = syscall.O_DIRECT
|
||||||
|
|
||||||
// fdatasync flushes written data to a file descriptor.
|
// fdatasync flushes written data to a file descriptor.
|
||||||
func fdatasync(f *os.File) error {
|
func fdatasync(db *DB) error {
|
||||||
return syscall.Fdatasync(int(f.Fd()))
|
return syscall.Fdatasync(int(db.file.Fd()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package bolt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
msAsync = 1 << iota // perform asynchronous writes
|
||||||
|
msSync // perform synchronous writes
|
||||||
|
msInvalidate // invalidate cached data
|
||||||
|
)
|
||||||
|
|
||||||
|
var odirect int
|
||||||
|
|
||||||
|
func msync(db *DB) error {
|
||||||
|
_, _, errno := syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(db.data)), uintptr(db.datasz), msInvalidate)
|
||||||
|
if errno != 0 {
|
||||||
|
return errno
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fdatasync(db *DB) error {
|
||||||
|
if db.data != nil {
|
||||||
|
return msync(db)
|
||||||
|
}
|
||||||
|
return db.file.Sync()
|
||||||
|
}
|
|
@ -11,8 +11,8 @@ import (
|
||||||
var odirect int
|
var odirect int
|
||||||
|
|
||||||
// fdatasync flushes written data to a file descriptor.
|
// fdatasync flushes written data to a file descriptor.
|
||||||
func fdatasync(f *os.File) error {
|
func fdatasync(db *DB) error {
|
||||||
return f.Sync()
|
return db.file.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
// flock acquires an advisory lock on a file descriptor.
|
// flock acquires an advisory lock on a file descriptor.
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
// +build !windows,!plan9,!linux
|
// +build !windows,!plan9,!linux,!openbsd
|
||||||
|
|
||||||
package bolt
|
package bolt
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
var odirect int
|
var odirect int
|
||||||
|
|
||||||
// fdatasync flushes written data to a file descriptor.
|
// fdatasync flushes written data to a file descriptor.
|
||||||
func fdatasync(f *os.File) error {
|
func fdatasync(db *DB) error {
|
||||||
return f.Sync()
|
return db.file.Sync()
|
||||||
}
|
}
|
||||||
|
|
12
db.go
12
db.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -23,6 +24,12 @@ const version = 2
|
||||||
// Represents a marker value to indicate that a file is a Bolt DB.
|
// Represents a marker value to indicate that a file is a Bolt DB.
|
||||||
const magic uint32 = 0xED0CDAED
|
const magic uint32 = 0xED0CDAED
|
||||||
|
|
||||||
|
// IgnoreNoSync specifies whether the NoSync field of a DB is ignored when
|
||||||
|
// syncing changes to a file. This is required as some operating systems,
|
||||||
|
// such as OpenBSD, do not have a unified buffer cache (UBC) and writes
|
||||||
|
// must be synchronzied using the msync(2) syscall.
|
||||||
|
const IgnoreNoSync = runtime.GOOS == "openbsd"
|
||||||
|
|
||||||
// DB represents a collection of buckets persisted to a file on disk.
|
// DB represents a collection of buckets persisted to a file on disk.
|
||||||
// All data access is performed through transactions which can be obtained through the DB.
|
// All data access is performed through transactions which can be obtained through the DB.
|
||||||
// All the functions on DB will return a ErrDatabaseNotOpen if accessed before Open() is called.
|
// All the functions on DB will return a ErrDatabaseNotOpen if accessed before Open() is called.
|
||||||
|
@ -39,6 +46,9 @@ type DB struct {
|
||||||
// a system failure or database corruption. Do not set this flag for
|
// a system failure or database corruption. Do not set this flag for
|
||||||
// normal use.
|
// normal use.
|
||||||
//
|
//
|
||||||
|
// If the package global IgnoreNoSync constant is true, this value is
|
||||||
|
// ignored. See the comment on that constant for more details.
|
||||||
|
//
|
||||||
// THIS IS UNSAFE. PLEASE USE WITH CAUTION.
|
// THIS IS UNSAFE. PLEASE USE WITH CAUTION.
|
||||||
NoSync bool
|
NoSync bool
|
||||||
|
|
||||||
|
@ -263,7 +273,7 @@ func (db *DB) init() error {
|
||||||
if _, err := db.ops.writeAt(buf, 0); err != nil {
|
if _, err := db.ops.writeAt(buf, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := fdatasync(db.file); err != nil {
|
if err := fdatasync(db); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
tx.go
8
tx.go
|
@ -425,8 +425,8 @@ func (tx *Tx) write() error {
|
||||||
// Update statistics.
|
// Update statistics.
|
||||||
tx.stats.Write++
|
tx.stats.Write++
|
||||||
}
|
}
|
||||||
if !tx.db.NoSync {
|
if !tx.db.NoSync || IgnoreNoSync {
|
||||||
if err := fdatasync(tx.db.file); err != nil {
|
if err := fdatasync(tx.db); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,8 +448,8 @@ func (tx *Tx) writeMeta() error {
|
||||||
if _, err := tx.db.ops.writeAt(buf, int64(p.id)*int64(tx.db.pageSize)); err != nil {
|
if _, err := tx.db.ops.writeAt(buf, int64(p.id)*int64(tx.db.pageSize)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !tx.db.NoSync {
|
if !tx.db.NoSync || IgnoreNoSync {
|
||||||
if err := fdatasync(tx.db.file); err != nil {
|
if err := fdatasync(tx.db); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue