{"record":{"id":"71279031b4faa487","repo":"benbjohnson/litestream","slug":"create-litestream-lock-table-w","errorCode":null,"errorMessage":"create _litestream_lock table: %w","messagePattern":"create _litestream_lock table: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":1092,"sourceCode":"\t// Enable WAL and ensure it is set. New mode should be returned on success:\n\t// https://www.sqlite.org/pragma.html#pragma_journal_mode\n\tvar mode string\n\tif err := db.db.QueryRowContext(ctx, `PRAGMA journal_mode = wal;`).Scan(&mode); err != nil {\n\t\treturn err\n\t} else if mode != \"wal\" {\n\t\treturn fmt.Errorf(\"enable wal failed, mode=%q\", mode)\n\t}\n\n\t// Create a table to force writes to the WAL when empty.\n\t// There should only ever be one row with id=1.\n\tif _, err := db.db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS _litestream_seq (id INTEGER PRIMARY KEY, seq INTEGER);`); err != nil {\n\t\treturn fmt.Errorf(\"create _litestream_seq table: %w\", err)\n\t}\n\n\t// Create a lock table to force write locks during sync.\n\t// The sync write transaction always rolls back so no data should be in this table.\n\tif _, err := db.db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS _litestream_lock (id INTEGER);`); err != nil {\n\t\treturn fmt.Errorf(\"create _litestream_lock table: %w\", err)\n\t}\n\n\t// Start a long-running read transaction to prevent other transactions\n\t// from checkpointing.\n\tif err := db.acquireReadLock(ctx); err != nil {\n\t\treturn fmt.Errorf(\"acquire read lock: %w\", err)\n\t}\n\n\t// Read page size.\n\tif err := db.db.QueryRowContext(ctx, `PRAGMA page_size;`).Scan(&db.pageSize); err != nil {\n\t\treturn fmt.Errorf(\"read page size: %w\", err)\n\t} else if db.pageSize <= 0 {\n\t\treturn fmt.Errorf(\"invalid db page size: %d\", db.pageSize)\n\t}\n\n\t// Ensure meta directory structure exists.\n\tif err := internal.MkdirAll(db.metaPath, db.dirInfo); err != nil {\n\t\treturn err","sourceCodeStart":1074,"sourceCodeEnd":1110,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L1074-L1110","documentation":"Litestream failed to create the `_litestream_lock` table during DB initialization. This table is used to force write locks during sync; sync transactions always roll back so no data remains in it. As with the seq-table error, the underlying driver error is wrapped and carries the real cause.","triggerScenarios":"The `CREATE TABLE IF NOT EXISTS _litestream_lock` ExecContext fails during db.init — same class of causes as the seq table: read-only file, SQLITE_BUSY from a concurrent writer, disk full, corrupted database, or the previous seq-table creation succeeded but state changed mid-init.","commonSituations":"Concurrent litestream processes on the same database racing through init; database locked by a long-running application write transaction; disk quota exceeded right after seq table creation; migrating from an older Litestream version with stale state.","solutions":["Ensure only one Litestream process monitors each database path.","Check/raise busy_timeout and retry while the conflicting writer finishes.","Verify disk space and write permissions on the database directory.","Run `PRAGMA integrity_check` to rule out corruption; restore from backup if corrupted."],"exampleFix":"// before\n# two litestream daemons started (systemd + manual) -> 'database is locked'\n// after\nsystemctl stop litestream; pkill -f 'litestream replicate'; systemctl start litestream","handlingStrategy":"try-catch","validationCode":"// ensure single writer: check for competing litestream processes and file writability\nfs.accessSync(dbPath, fs.constants.W_OK);","typeGuard":"function canAcquireWrite(path) { try { return fs.accessSync(path, fs.constants.W_OK) === undefined; } catch { return false; } }","tryCatchPattern":"try {\n  await db.Open(ctx);\n} catch (err) {\n  if (String(err.message).includes('create _litestream_lock table')) {\n    if (String(err.cause).includes('locked')) { await sleep(backoff); retry(); }\n    else throw err;\n  }\n}","preventionTips":["Use process supervision (systemd) with a singleton so only one litestream runs.","Keep application write transactions short to avoid prolonged SQLITE_BUSY.","Set a generous busy_timeout on the SQLite connection.","Watch for disk-full alerts."],"tags":["sqlite","database","init","locking"],"backgroundTag":"database-write-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}