Add checkpoint interval

This commit is contained in:
Ben Johnson
2020-12-30 12:07:02 -07:00
parent d4891f33da
commit 0b12efb135

16
db.go
View File

@@ -22,6 +22,7 @@ import (
// Default DB settings. // Default DB settings.
const ( const (
DefaultMonitorInterval = 1 * time.Second DefaultMonitorInterval = 1 * time.Second
DefaultCheckpointInterval = 5 * time.Second // 1 * time.Minute
DefaultMinCheckpointPageN = 1000 DefaultMinCheckpointPageN = 1000
) )
@@ -39,6 +40,8 @@ type DB struct {
cancel func() cancel func()
wg sync.WaitGroup wg sync.WaitGroup
lastCheckpointAt time.Time // last checkpoint time
// Minimum threshold of WAL size, in pages, before a passive checkpoint. // Minimum threshold of WAL size, in pages, before a passive checkpoint.
// A passive checkpoint will attempt a checkpoint but fail if there are // A passive checkpoint will attempt a checkpoint but fail if there are
// active transactions occurring at the same time. // active transactions occurring at the same time.
@@ -52,6 +55,11 @@ type DB struct {
// unbounded if there are always read transactions occurring. // unbounded if there are always read transactions occurring.
MaxCheckpointPageN int MaxCheckpointPageN int
// Time between automatic checkpoints in the WAL. This is done to allow
// more fine-grained WAL files so that restores can be performed with
// better precision.
CheckpointInterval time.Duration
// List of replicas for the database. // List of replicas for the database.
// Must be set before calling Open(). // Must be set before calling Open().
Replicas []Replica Replicas []Replica
@@ -67,6 +75,7 @@ func NewDB(path string) *DB {
notify: make(chan struct{}), notify: make(chan struct{}),
MinCheckpointPageN: DefaultMinCheckpointPageN, MinCheckpointPageN: DefaultMinCheckpointPageN,
CheckpointInterval: DefaultCheckpointInterval,
MonitorInterval: DefaultMonitorInterval, MonitorInterval: DefaultMonitorInterval,
} }
db.ctx, db.cancel = context.WithCancel(context.Background()) db.ctx, db.cancel = context.WithCancel(context.Background())
@@ -501,6 +510,8 @@ func (db *DB) Sync() (err error) {
checkpoint = true checkpoint = true
} else if db.MaxCheckpointPageN > 0 && newWALSize >= calcWALSize(db.pageSize, db.MaxCheckpointPageN) { } else if db.MaxCheckpointPageN > 0 && newWALSize >= calcWALSize(db.pageSize, db.MaxCheckpointPageN) {
checkpoint, checkpointMode = true, CheckpointModeRestart checkpoint, checkpointMode = true, CheckpointModeRestart
} else if db.CheckpointInterval > 0 && time.Since(db.lastCheckpointAt) > db.CheckpointInterval && newWALSize > calcWALSize(db.pageSize, 1) {
checkpoint = true
} }
// Release write lock before checkpointing & exiting. // Release write lock before checkpointing & exiting.
@@ -558,6 +569,7 @@ func (db *DB) verify() (info syncInfo, err error) {
return info, err return info, err
} }
info.walSize = fi.Size() info.walSize = fi.Size()
info.walModTime = fi.ModTime()
// Open shadow WAL to copy append to. // Open shadow WAL to copy append to.
info.shadowWALPath, err = db.CurrentShadowWALPath(info.generation) info.shadowWALPath, err = db.CurrentShadowWALPath(info.generation)
@@ -623,6 +635,7 @@ func (db *DB) verify() (info syncInfo, err error) {
type syncInfo struct { type syncInfo struct {
generation string // generation name generation string // generation name
walSize int64 // size of real WAL file walSize int64 // size of real WAL file
walModTime time.Time // last modified date of real WAL file
shadowWALPath string // name of last shadow WAL file shadowWALPath string // name of last shadow WAL file
shadowWALSize int64 // size of last shadow WAL file shadowWALSize int64 // size of last shadow WAL file
restart bool // if true, real WAL header does not match shadow WAL restart bool // if true, real WAL header does not match shadow WAL
@@ -936,6 +949,9 @@ func (db *DB) checkpoint(mode string) error {
if err := db.acquireReadLock(); err != nil { if err := db.acquireReadLock(); err != nil {
return fmt.Errorf("release read lock: %w", err) return fmt.Errorf("release read lock: %w", err)
} }
db.lastCheckpointAt = time.Now()
return nil return nil
} }