database: Use "write-ahead log" mode and set a long "busy timeout".

This should avoid "database is locked" errors when there's a lot of
concurrency, for instance when offloading simultaneously a lot of
builds.

* guix/store/database.scm (call-with-database): Add two 'sqlite-exec'
calls to set 'journal_mode' and 'busy_timeout'.
This commit is contained in:
Ludovic Courtès 2018-12-21 23:35:20 +01:00
parent b96e05aefd
commit bdf860c2e9
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
1 changed files with 9 additions and 0 deletions

View File

@ -79,6 +79,15 @@ as specified by SQL-SCHEMA."
create it and initialize it as a new database." create it and initialize it as a new database."
(let ((new? (not (file-exists? file))) (let ((new? (not (file-exists? file)))
(db (sqlite-open file))) (db (sqlite-open file)))
;; Turn DB in "write-ahead log" mode, which should avoid SQLITE_LOCKED
;; errors when we have several readers: <https://www.sqlite.org/wal.html>.
(sqlite-exec db "PRAGMA journal_mode=WAL;")
;; Install a busy handler such that, when the database is locked, sqlite
;; retries until 30 seconds have passed, at which point it gives up and
;; throws SQLITE_BUSY.
(sqlite-exec db "PRAGMA busy_timeout = 30000;")
(dynamic-wind noop (dynamic-wind noop
(lambda () (lambda ()
(when new? (when new?