Set MaxOpenConns(1) to eliminate SQLite SQLITE_BUSY errors

Go's database/sql opens multiple connections by default, but SQLite
only supports one concurrent writer. Under concurrent load (e.g.
parallel blob uploads to MCR), multiple connections compete for the
write lock and exceed busy_timeout, causing transient 500 errors.

With WAL mode, a single connection still allows concurrent reads
from other processes. Go serializes access through the connection
pool, eliminating busy errors entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 23:28:46 -07:00
parent 4c7610ce6b
commit 20d8d8d4b4

View File

@@ -59,6 +59,12 @@ func Open(path string) (*sql.DB, error) {
}
}
// SQLite supports concurrent readers but only one writer. With WAL mode,
// reads don't block writes, but multiple Go connections competing for
// the write lock causes SQLITE_BUSY under concurrent load. Limit to one
// connection to serialize all access and eliminate busy errors.
database.SetMaxOpenConns(1)
// Ensure permissions are correct even if the file already existed.
if err := os.Chmod(path, 0600); err != nil {
_ = database.Close()