Skip to content

1.0.5: wait for the WAL switch on a store being migrated - #21

Merged
ilien-dev merged 1 commit into
masterfrom
feature/fix-empty-store-migration-race
Oct 8, 2026
Merged

ilien-dev merged 1 commit into
masterfrom
feature/fix-empty-store-migration-race

Conversation

@ilien-dev

Copy link
Copy Markdown
Owner

The test job on master failed on four pushes, each time in s10_schema_versions of the fault suite. The scenario puts an empty file where the store should be, runs SessionStart and SessionEnd, and expects the store migrated. Depending on the run it found a RED status, "no such table: meta", or a newer schema that was not refused. 1.0.3 fixed the last of the three.

The other two come from the first statement a write open runs, PRAGMA journal_mode=WAL. On a file that is not in WAL mode yet, SQLite needs an exclusive lock for the switch and takes it without calling the busy handler. SessionStart launches a detached maintain, and when that process was in the file, the SessionEnd hook got "database is locked" at once, exited 0 and left the store without its schema. The 700 ms busy_timeout never applied.

Db::open_with_busy now retries the switch for as long as the same busy_ms allows, using the backoff steps the read path already has. Only the ReadWrite open changes, so the read hooks are untouched.

writers_racing_to_open_an_empty_store_all_migrate_it in muninn-core opens an empty file from four threads at once. Before the change it failed in under 0.1 s on each of 8 runs on Windows. After it, it passed 5 of 5.

The branch-name failure on #20 is separate: the CLA bot's cla-signatures branch does not match the naming rule. This PR does not change that.

Checked with the change in place: fmt, clippy and the workspace tests on Windows; in a Linux container, the fault suite at 200 repetitions twice (17 of 17 both times), the boot block budget, and perf --strict with the CI scale of 1.5. The fault suite did not fail in that container before the change either (2 runs), so the proof that the race is closed is the new test and the next pushes to master.

Opening the store for writing starts with PRAGMA journal_mode=WAL. On a file not
in WAL mode yet SQLite takes the exclusive lock for that switch without calling
the busy handler, so with a second writer in the file (the detached maintain) the
pragma failed at once with SQLITE_BUSY and the hook exited 0 without migrating.
The switch now retries inside the open's own busy budget. This is what failed
s10_schema_versions on master's CI.
@ilien-dev

Copy link
Copy Markdown
Owner Author

recheck

@ilien-dev
ilien-dev merged commit 23b8361 into master Oct 8, 2026
13 of 14 checks passed
@ilien-dev
ilien-dev deleted the feature/fix-empty-store-migration-race branch October 8, 2026 17:37
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant