Skip to content

Commit

Permalink
Add DB.NoTruncate flag.
Browse files Browse the repository at this point in the history
This commit adds the DB.NoTruncate flag to optionally revert mmap()
calls to how they were implemented before the ext3/ext4 fix. When
NoTruncate is true, remapping the data file will not force the file
system to resize it immediately. This works for non-ext3/4 file
systems.

The default value of NoTruncate is false so it is still safe for
ext3/ext4 file systems by default.

See also: boltdb#284
  • Loading branch information
benbjohnson committed May 5, 2015
1 parent 550b8c7 commit cafb3f6
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
12 changes: 7 additions & 5 deletions bolt_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ func funlock(f *os.File) error {
func mmap(db *DB, sz int) error {
// Truncate and fsync to ensure file size metadata is flushed.
// https://github.com/boltdb/bolt/issues/284
if err := db.file.Truncate(int64(sz)); err != nil {
return fmt.Errorf("file resize error: %s", err)
}
if err := db.file.Sync(); err != nil {
return fmt.Errorf("file sync error: %s", err)
if !db.NoTruncate {
if err := db.file.Truncate(int64(sz)); err != nil {
return fmt.Errorf("file resize error: %s", err)
}
if err := db.file.Sync(); err != nil {
return fmt.Errorf("file sync error: %s", err)
}
}

// Map the data file to memory.
Expand Down
13 changes: 12 additions & 1 deletion db.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ type DB struct {
// THIS IS UNSAFE. PLEASE USE WITH CAUTION.
NoSync bool

// When true, skips the truncate call when resizing the database.
// Setting this to true is only save on non-ext3/ext4 systems.
//
// https://github.com/boltdb/bolt/issues/284
NoTruncate bool

// MaxBatchSize is the maximum size of a batch. Default value is
// copied from DefaultMaxBatchSize in Open.
//
Expand Down Expand Up @@ -123,6 +129,7 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) {
if options == nil {
options = DefaultOptions
}
db.NoTruncate = options.NoTruncate

// Set default values for later DB operations.
db.MaxBatchSize = DefaultMaxBatchSize
Expand Down Expand Up @@ -613,12 +620,16 @@ type Options struct {
// When set to zero it will wait indefinitely. This option is only
// available on Darwin and Linux.
Timeout time.Duration

// Sets the DB.NoTruncate flag before memory mapping the file.
NoTruncate bool
}

// DefaultOptions represent the options used if nil options are passed into Open().
// No timeout is used which will cause Bolt to wait indefinitely for a lock.
var DefaultOptions = &Options{
Timeout: 0,
Timeout: 0,
NoTruncate: false,
}

// Stats represents statistics about the database.
Expand Down
1 change: 0 additions & 1 deletion db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ func TestOpen_Size(t *testing.T) {
// Reopen database, update, and check size again.
db0, err := bolt.Open(path, 0666, nil)
ok(t, err)
ok(t, db0.Update(func(tx *bolt.Tx) error { return tx.Bucket([]byte("data")).Put([]byte{0}, []byte{0}) }))
ok(t, db0.Close())
newSz := fileSize(path)
if newSz == 0 {
Expand Down

0 comments on commit cafb3f6

Please sign in to comment.