From c8961ad489046ffa5522fa9f56054f413af77978 Mon Sep 17 00:00:00 2001 From: Lincoln Nogueira Date: Thu, 20 Jul 2023 09:51:25 -0300 Subject: [PATCH] fix: database is locked (#1992) * fix: database is locked The option "_journal_mode=WAL" is currently *not* being applied when provided in the DSN. This issue affects only new memos installations, not older ones where the database journal was properly set to WAL mode by the previous sqlite library go-sqlite3. modernc.org/sqlite DSN parsing is different from go-sqlite3. It requires the `_pragma=` prefix and even some options order matter. https://gitlab.com/cznic/sqlite/-/issues/115 Closes #1985 * chore: upgraded notes on sqlite DSN --- store/db/db.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/store/db/db.go b/store/db/db.go index d210fa2b4..df0cdc531 100644 --- a/store/db/db.go +++ b/store/db/db.go @@ -42,8 +42,21 @@ func (db *DB) Open(ctx context.Context) (err error) { return fmt.Errorf("dsn required") } - // Connect to the database without foreign_key. - sqliteDB, err := sql.Open("sqlite", db.profile.DSN+"?cache=private&_foreign_keys=0&_busy_timeout=10000&_journal_mode=WAL") + // Connect to the database with some sane settings: + // - No shared-cache: it's obsolete; WAL journal mode is a better solution. + // - No foreign key constraints: it's currently disabled by default, but it's a + // good practice to be explicit and prevent future surprises on SQLite upgrades. + // - Journal mode set to WAL: it's the recommended journal mode for most applications + // as it prevents locking issues. + // + // Notes: + // - When using the `modernc.org/sqlite` driver, each pragma must be prefixed with `_pragma=`. + // + // References: + // - https://pkg.go.dev/modernc.org/sqlite#Driver.Open + // - https://www.sqlite.org/sharedcache.html + // - https://www.sqlite.org/pragma.html + sqliteDB, err := sql.Open("sqlite", db.profile.DSN+"?_pragma=foreign_keys(0)&_pragma=busy_timeout(10000)&_pragma=journal_mode(WAL)") if err != nil { return fmt.Errorf("failed to open db with dsn: %s, err: %w", db.profile.DSN, err) }