Skip to content

fix(memory): open sqlite db under file lock to avoid SQLITE_BUSY races#3538

Merged
dgageot merged 1 commit into
mainfrom
fix/memory-sqlite-open-under-lock
Jul 8, 2026
Merged

fix(memory): open sqlite db under file lock to avoid SQLITE_BUSY races#3538
dgageot merged 1 commit into
mainfrom
fix/memory-sqlite-open-under-lock

Conversation

@dgageot

@dgageot dgageot commented Jul 8, 2026

Copy link
Copy Markdown
Member

TestConcurrentAddsPreserveAllRows was flaky, failing with database is locked (5) (SQLITE_BUSY), reliably reproducible with go test -run TestConcurrent -count=10 -race ./pkg/memory/database/sqlite/. The root cause was in MemoryDatabase.ensureDB: sqliteutil.OpenDB was called before acquiring the advisory file lock. Opening pings the database and the journal_mode(WAL) DSN pragma converts a fresh database to WAL mode; that conversion needs an exclusive lock and is not retried by busy_timeout. With multiple workers opening the same brand-new file concurrently, first-open attempts raced and whole workers failed.

The fix moves the OpenDB call to after the file lock is acquired, so the open, WAL conversion, and schema migration all happen under the lock. The lock is already held for migrations; extending its scope one step earlier costs nothing and eliminates the race entirely.

No behaviour changes for existing callers. TestConcurrent* now passes 30 iterations with -race where it previously failed within 10.

In ensureDB, OpenDB was called before acquiring the file lock; the first
open of a fresh database converts it to WAL mode which needs an exclusive
lock not covered by busy_timeout, so concurrent first-opens could race.
Moving lock acquisition before OpenDB ensures open + WAL conversion +
schema migration all run under the lock.

Assisted-By: Claude
@dgageot
dgageot requested a review from a team as a code owner July 8, 2026 13:57
@aheritier aheritier added area/rag For work/issues that have to do with the RAG features kind/fix PR fixes a bug (maps to fix:). Use on PRs only. labels Jul 8, 2026
@dgageot
dgageot merged commit 368855d into main Jul 8, 2026
14 checks passed
@dgageot
dgageot deleted the fix/memory-sqlite-open-under-lock branch July 8, 2026 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/rag For work/issues that have to do with the RAG features kind/fix PR fixes a bug (maps to fix:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants