Ai! Jack!v2026.04.01-f12
← 홈HN New

Busy_timeout order matters in SQLite connection string

원문 보기HN에서 보기
1 pointsby freshteapot

AI 분석

•SQLite의 WAL 전환 중 잠금 대기를 위해 busy_timeout 선행 설정이 중요하다는 설명
•실제 적용 순서는 드라이버별 동작이며, modernc.org/sqlite v1.57.0은 busy_timeout을 먼저 배치하는 구조
•연결 문자열의 표기 순서만 믿지 말고 드라이버 버전과 초기화 순서 확인 필요

검증 정보

출처
freshteapot.net
피드
HN New
수집/분석 기준
2026. 9. 8. 오전 9:00
원문 확인
원문 열기

본문

When SQLite connection string order is API semantics | Chris Skip to content ~/ freshteapot writing projects now about home / writing / when sqlite connection string order is api semantics Writing When SQLite connection string order is API semantics How two Go SQLite drivers handle pragma order, and why busy_timeout belongs before journal_mode. Published 8 Sep 2026 · 3 min read #Go #Sqlite On this page ⌄ Two drivers, two interfaces A short history Searched for References I was configuring two Go services to share a SQLite database. The connection string included a busy timeout and WAL mode: ?_busy_timeout=10000&_journal_mode=WAL Then I found a comment in PocketBase : busy_timeout must be set first so that the connection will wait if switching to WAL encounters a busy database. This is one of those cases where string order can be API semantics, not just presentation. The precise behaviour, however, belongs to the database driver. Two drivers, two interfaces PocketBase uses modernc.org/sqlite and supplies repeated generic _pragma parameters: ?_pragma=busy_timeout(10000)&_pragma=journal_mode(WAL) In modernc.org/sqlite v1.57.0 , the driver collects those values, moves busy_timeout first, sorts the rest, and then executes them. The order written by the caller expresses the intention, but this version of the driver also enforces the important part. github.com/mattn/go-sqlite3 presents dedicated options instead: ?_busy_timeout=10000&_journal_mode=WAL It parses the query string into named parameters , then applies them in its own fixed order. It sets PRAGMA busy_timeout well before PRAGMA journal_mode . Swapping those two options in the original string does not change their execution order. The lesson is small but useful: do not infer connection initialisation order from the appearance of a DSN. Read the driver. PocketBase’s comment explained why the ordering matters; the two driver implementations showed where that ordering actually comes from. A short history There is a direct trail for the behaviour in modernc.org/sqlite . In November 2024, a user reported intermittent SQLITE_BUSY errors while opening pooled connections. Their DSN placed busy_timeout after journal_mode(WAL) . A new connection could therefore attempt to set WAL before installing its busy handler, and fail immediately if another connection held the required lock. The reporter compared the behaviour with mattn/go-sqlite3 . Mattn’s driver already applied busy_timeout early, regardless of its position in the DSN. In the diagnostic comment , they showed that applying busy_timeout first stopped the errors. They then proposed a consistent pragma order . The maintainer confirmed that the suggestion had been incorporated in the fix titled apply busy_timeout pragma early . The root cause lies in SQLite itself. busy_timeout installs a busy handler on a connection. Changing journal_mode changes persistent database state and may need a lock. The handler must be ready before that work begins. The sequence is therefore: SQLite’s locking semantics, Mattn’s established ordering, a reproducible failure in modernc , an upstream fix, and PocketBase’s concise comment preserving the reason. Searched for busy_timeout sqlite modernc sqlite pragma order SQLITE_BUSY mattn go-sqlite3 busy_timeout journal_mode order References PocketBase: SQLite connection setup and ordering comment modernc.org/sqlite v1.57.0: pragma ordering modernc.org/sqlite issue 198: diagnosis and comp

댓글 1개

freshteapot

Today I learnt that it is not enough to add busy_timeout to the query path, when opening a sqlite database.

I found a hint in a comment in the the pocketbase code base and from there, I went on a side quest (down the rabbit hole) and learnt more about why busy_timeout needs to be at the front.

관련 아이템