Enforce max WAL index.

This commit sets a hard upper limit for the WAL index to (1<<31)-1.
The index is hex-encoded in file names as a 4-byte unsigned integer
so limit ensures all index values are below any upper limit and are
unaffected by any signed int limit.

A WAL file is typically at least 4MB so you would need to write
8 petabytes to reach this upper limit.
This commit is contained in:
Ben Johnson
2021-02-02 15:11:50 -07:00
parent 6c49fba592
commit 6fd11ccab5

12
db.go
View File

@@ -33,6 +33,10 @@ const (
DefaultMaxCheckpointPageN = 10000 DefaultMaxCheckpointPageN = 10000
) )
// MaxIndex is the maximum possible WAL index.
// If this index is reached then a new generation will be started.
const MaxIndex = 0x7FFFFFFF
// BusyTimeout is the timeout to wait for EBUSY from SQLite. // BusyTimeout is the timeout to wait for EBUSY from SQLite.
const BusyTimeout = 1 * time.Second const BusyTimeout = 1 * time.Second
@@ -844,10 +848,14 @@ func (db *DB) verify() (info syncInfo, err error) {
db.walSizeGauge.Set(float64(fi.Size())) db.walSizeGauge.Set(float64(fi.Size()))
// Open shadow WAL to copy append to. // Open shadow WAL to copy append to.
info.shadowWALPath, err = db.CurrentShadowWALPath(info.generation) index, _, err := db.CurrentShadowWALIndex(info.generation)
if err != nil { if err != nil {
return info, fmt.Errorf("cannot determine shadow WAL: %w", err) return info, fmt.Errorf("cannot determine shadow WAL index: %w", err)
} else if index >= MaxIndex {
info.reason = "max index exceeded"
return info, nil
} }
info.shadowWALPath = db.ShadowWALPath(generation, index)
// Determine shadow WAL current size. // Determine shadow WAL current size.
fi, err = os.Stat(info.shadowWALPath) fi, err = os.Stat(info.shadowWALPath)