From 881a9347e88fb100468ae1335053d2fc9b9fb10f Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Fri, 18 Sep 2026 20:57:49 +0200 Subject: [PATCH] fix(db): enable WAL + busy_timeout on SQLite connections (#2917) Uploads and cron jobs intermittently failed with "database is locked" (SQLITE_BUSY) until restart. The custom sqlite3 driver only set foreign_keys; it now also enables WAL, synchronous=NORMAL, and a 5s busy_timeout on every new connection so cross-connection contention waits instead of erroring instantly. MaxOpenConns stays at 1: a single connection serializes statements, which avoids same-connection read-cursor/write conflicts that busy_timeout cannot retry. Authored By: TDvorak Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- inventory/client.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/inventory/client.go b/inventory/client.go index 2a1ac1f4..b51d29cf 100644 --- a/inventory/client.go +++ b/inventory/client.go @@ -149,9 +149,18 @@ func (d sqlite3Driver) Open(name string) (conn driver.Conn, err error) { if err != nil { return } - _, err = conn.(sqlite3DriverConn).Exec("PRAGMA foreign_keys = ON;", nil) - if err != nil { - _ = conn.Close() + // WAL lets readers coexist with the writer; busy_timeout makes a brief + // lock wait instead of failing instantly with SQLITE_BUSY (#2917). + for _, pragma := range []string{ + "PRAGMA journal_mode = WAL;", + "PRAGMA synchronous = NORMAL;", + "PRAGMA busy_timeout = 5000;", + "PRAGMA foreign_keys = ON;", + } { + if _, err = conn.(sqlite3DriverConn).Exec(pragma, nil); err != nil { + _ = conn.Close() + return + } } return }