Add DB.NoSync option for bulk loading.

This commit adds the DB.NoSync flag to skip fsync() calls on each commit. This should only
be used for bulk loading as it can corrupt your database in the event of a system failure.

Initial tests show it can provide a 2x speed up for sequential inserts.
pull/34/head
Ben Johnson 2014-07-15 07:37:46 -06:00
parent 1395a04d97
commit 048d3f19b2
4 changed files with 21 additions and 4 deletions

View File

@ -46,6 +46,7 @@ func Bench(options *BenchOptions) {
fatal(err) fatal(err)
return return
} }
db.NoSync = options.NoSync
db.FillPercent = options.FillPercent db.FillPercent = options.FillPercent
defer db.Close() defer db.Close()
@ -363,6 +364,7 @@ type BenchOptions struct {
BlockProfile string BlockProfile string
StatsInterval time.Duration StatsInterval time.Duration
FillPercent float64 FillPercent float64
NoSync bool
Clean bool Clean bool
} }

View File

@ -118,6 +118,7 @@ func NewApp() *cli.App {
&cli.StringFlag{Name: "blockprofile", Usage: "Block profile output path"}, &cli.StringFlag{Name: "blockprofile", Usage: "Block profile output path"},
&cli.StringFlag{Name: "stats-interval", Value: "0s", Usage: "Continuous stats interval"}, &cli.StringFlag{Name: "stats-interval", Value: "0s", Usage: "Continuous stats interval"},
&cli.Float64Flag{Name: "fill-percent", Value: bolt.DefaultFillPercent, Usage: "Fill percentage"}, &cli.Float64Flag{Name: "fill-percent", Value: bolt.DefaultFillPercent, Usage: "Fill percentage"},
&cli.BoolFlag{Name: "no-sync", Usage: "Skip fsync on every commit"},
&cli.BoolFlag{Name: "work", Usage: "Print the temp db and do not delete on exit"}, &cli.BoolFlag{Name: "work", Usage: "Print the temp db and do not delete on exit"},
}, },
Action: func(c *cli.Context) { Action: func(c *cli.Context) {
@ -139,6 +140,7 @@ func NewApp() *cli.App {
BlockProfile: c.String("blockprofile"), BlockProfile: c.String("blockprofile"),
StatsInterval: statsInterval, StatsInterval: statsInterval,
FillPercent: c.Float64("fill-percent"), FillPercent: c.Float64("fill-percent"),
NoSync: c.Bool("no-sync"),
Clean: !c.Bool("work"), Clean: !c.Bool("work"),
}) })
}, },

9
db.go
View File

@ -47,6 +47,15 @@ type DB struct {
// amount if you know that your write workloads are mostly append-only. // amount if you know that your write workloads are mostly append-only.
FillPercent float64 FillPercent float64
// Setting the NoSync flag will cause the database to skip fsync()
// calls after each commit. This can be useful when bulk loading data
// into a database and you can restart the bulk load in the event of
// a system failure or database corruption. Do not set this flag for
// normal use.
//
// THIS IS UNSAFE. PLEASE USE WITH CAUTION.
NoSync bool
path string path string
file *os.File file *os.File
dataref []byte dataref []byte

12
tx.go
View File

@ -425,8 +425,10 @@ func (tx *Tx) write() error {
// Update statistics. // Update statistics.
tx.stats.Write++ tx.stats.Write++
} }
if err := fdatasync(tx.db.file); err != nil { if !tx.db.NoSync {
return err if err := fdatasync(tx.db.file); err != nil {
return err
}
} }
// Clear out page cache. // Clear out page cache.
@ -446,8 +448,10 @@ 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 err := fdatasync(tx.db.file); err != nil { if !tx.db.NoSync {
return err if err := fdatasync(tx.db.file); err != nil {
return err
}
} }
// Update statistics. // Update statistics.