Skip to content

Database: WAL, batched clears of deletion records, and giving free space back - #53

Open
ChakraFusion wants to merge 3 commits into
Liquid-co:dev-publicfrom
ChakraFusion:pr/database-wal
Open

ChakraFusion wants to merge 3 commits into
Liquid-co:dev-publicfrom
ChakraFusion:pr/database-wal

Conversation

@ChakraFusion

Copy link
Copy Markdown

As offered in #21. Three commits:

  1. Incremental auto-vacuum: a one-time VACUUM when the database is opened, then free pages handed back at open and hourly. On one PC, 663 MB became 380 MB.
  2. WAL with synchronous=NORMAL, and deletion records cleared in one transaction when a save is put back or files reappear. Putting a 240k-file save back had spent most of an hour creating and deleting a rollback journal per row.
  3. 500 paths per DELETE: 50,000 records in about 0.3 s, versus 10 s with one statement per path under the race detector.

Nothing copies opensave.db directly; everything goes through store.Open, so the -wal file needs no special handling.

Tests: the database uses WAL; compaction gives space back (using a table of the test's own); clearing 50,000 records is one transaction and fast.

🤖 Generated with Claude Code

ChakraFusion and others added 3 commits October 13, 2026 20:30
opensave.db had grown to 663 MB on one device, 262 MB of it pages that
deleted rows had left: SQLite never shrinks the file on its own, and
snapshots - each with a row per file of its save, a quarter of a million
for one game - are merged, pruned and replaced all the time.

The database is switched to incremental auto-vacuum, which takes one full
VACUUM when it is opened (8 seconds for that database, 663 to 380 MB).
After that its free pages are handed back a few at a time - when it is
opened and hourly - so deleting a snapshot makes the file smaller.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Putting Project Zomboid back after its folder was emptied spent most of
an hour in the database, the save untouched meanwhile: every file's
deletion record was cleared with a statement of its own, a quarter of a
million of them, and with SQLite's default rollback journal every one of
them created, flushed and deleted a journal file.

- Deletion records are cleared in one transaction per save location, on
  putting a save back and when files come back in a snapshot
  (ClearDeletedFiles): 50,000 take a third of a second.
- The database runs in WAL mode with synchronous NORMAL: writes are
  appended to one log instead of each making a journal file of its own.
  The database stays whole whatever happens; a power cut can cost only the
  last moments' writes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
One statement per path, even inside one transaction, took 10s for 50,000
records under the race detector on CI's runners, and the test's limit
failed. 500 paths to a statement: 50,000 records in about 0.3s here. The
test's limit is generous now (30s): what it guards against took minutes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@vercel

vercel Bot commented Oct 14, 2026

Copy link
Copy Markdown

@ChakraFusion is attempting to deploy a commit to the sivadaboi's projects Team on Vercel.

A member of the Team first needs to authorize it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant