Remove SQLite write lock during WAL sync (again)

This commit reattempts a change to remove the write lock that was
previously tried in 998e831. This change will reduce the number of
locks on the database which should help reduce error messages that
applications see when they do not have busy_timeout set.

In addition to the lock removal, a passive checkpoint is issued
immediately before the read lock is obtained to prevent additional
checkpoints by the application itself. SQLite does not support
checkpoints from an active transaction so it cannot be done afterward.
This commit is contained in:
Ben Johnson
2021-04-22 16:35:04 -06:00
parent 73f8de23a6
commit 1d1fd6e686
3 changed files with 10 additions and 26 deletions

View File

@@ -649,6 +649,11 @@ func (r *Replica) snapshot(ctx context.Context, generation string, index int) er
r.muf.Lock()
defer r.muf.Unlock()
// Issue a passive checkpoint to flush any pages to disk before snapshotting.
if _, err := r.db.SQLDB().ExecContext(ctx, `PRAGMA wal_checkpoint(PASSIVE);`); err != nil {
return fmt.Errorf("pre-snapshot checkpoint: %w", err)
}
// Acquire a read lock on the database during snapshot to prevent checkpoints.
tx, err := r.db.SQLDB().Begin()
if err != nil {