Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

[Bug]: SQLite WAL is never checkpointed — clean exit leaves a multi-MB -wal file

Offen
#505 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
74/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
sqlite, typescript
Bereich
database

Rechercherichtung

Start with packages/local-runtime-v2/src/infra/db/client.ts and runtime.ts to trace database initialization and the closeRuntime() shutdown path. Add the proposed checkpoint behavior and tests for WAL truncation with rows preserved and for closed clients; run the new tests and packages/local-runtime-v2/src/services.test.ts. Done means clean startup and shutdown truncate the WAL without losing committed rows or making close fail.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

tui
Product or interface

CLI - interactive TUI

Version
  • @minimax-ai/code 0.6.12 (npm, Linux)
  • Reproduced from source at commit 9a935605956c4500e9cb415f29258e2887e97817 (repository package version 0.6.5)
  • Node.js 24.21.0
Platform

Linux

OS version and architecture

Linux 7.2.9 x64 (NixOS)

Issue area

File / workspace / path / encoding

Steps to reproduce
  1. Use mcode normally for a few sessions, or run one mcode exec turn in a fresh profile.
  2. Exit cleanly (no kill, no crash).
  3. Inspect the SQLite files:
ls -l ~/.minimax/v2/sqlite/runtime-state.sqlite*

Minimal one-turn repro:

mcode exec --permission off "Reply with exactly OK"
ls -l ~/.minimax/v2/sqlite/runtime-state.sqlite*
Expected and actual behavior

Expected: a clean exit leaves a small or zero-byte -wal, with committed pages checkpointed into the main database file.

Actual: the WAL persists at multi-megabyte size after the process exits. On a fresh profile, one trivial turn leaves:

runtime-state.sqlite        4 KB
runtime-state.sqlite-wal 3,798 KB

The main DB is only 4 KB because the turn's data still lives in the WAL. Nothing in 0.6.12 ever runs wal_checkpoint.

Evidence

Same-revision comparison (build from 9a93560, identical one-turn exec, isolated HOME, measured after exit):

Build runtime-state.sqlite -wal
HEAD (unpatched) 4 KB 3,283 KB
HEAD + checkpoint patch (below) 964 KB 0 KB

Installed 0.6.12 shows the same: 3,798 KB -wal, 4 KB main file.

Startup reclaim: a profile left with a 3,798 KB WAL, started with the patched build, ends at 0 KB with the DB at 1,116 KB.

Cost on a real database (247 MB main file, 17.6 MB WAL): PRAGMA wal_checkpoint(TRUNCATE) takes 26.7 ms and takes the WAL from 17.6 MB to 0. A real checkpoint of 21 MB / 5,334 frames (autocheckpoint disabled) takes 70.7 ms.

Static check of the 0.6.12 bundle and upstream main: PRAGMA journal_mode = WAL is set in packages/local-runtime-v2/src/infra/db/client.ts, and there is no wal_checkpoint, journal_size_limit, auto_vacuum, or PRAGMA optimize anywhere. main still has no checkpoint, and no open PR implements one.

Root cause
  • client.ts opens the DB with journal_mode = WAL, busy_timeout, foreign_keys — and nothing else.
  • close() closes the handle without a checkpoint.
  • The only close path is runtime.ts closeRuntime(); no startup or periodic checkpoint runs.
  • SQLite's default wal_autocheckpoint = 1000 pages backfills pages into the main DB but does not reset the WAL file, so the -wal keeps its high-water size.
Proposed fix

Two checkpoints, ~18 added lines:

  1. DatabaseClient.checkpoint(mode = 'PASSIVE') — no-op when closed, best-effort PRAGMA wal_checkpoint(<mode>).
  2. close() calls checkpoint('TRUNCATE') before closing.
  3. After initializeDatabase() resolves in runtime.ts, a synchronous checkpoint('TRUNCATE') (measured as db_checkpoint_ms) reclaims a WAL left by a crash or a previous long session.

Plus two tests: truncation shrinks the WAL to 0 while preserving rows, and no throw on closed/never-opened clients.

Deliberately excluded: journal_size_limit (measured as a null result — 0, 4 MiB and -1 all left the same 21 MB WAL) and wal_autocheckpoint=1000 (already SQLite's default).

Validation
  • tsc -p tsconfig.standalone.json --noEmit → exit 0
  • new test → 2/2; packages/local-runtime-v2/src/services.test.ts → 64/64
  • scripts/source-inventory.mjs → 4,356 files, passed
  • build → bundle contains wal_checkpoint and db_checkpoint_ms
  • end-to-end numbers above, on an otherwise idle profile
Scope and limitations
  • This is not a fix for #496's retention/RSS report. It does not touch the retention queue, orphan rows, transcript storage, or RSS; it only bounds the WAL file at startup and shutdown.
  • Long-running sessions are not covered: the file is truncated at start/close, not periodically.
  • The TUI shutdown path shares closeRuntime() with exec by code inspection, but only exec was measured end-to-end.
  • A checkpoint attempted while another connection holds a write transaction fails with database table is locked; the error is deliberately swallowed so shutdown cannot fail. It degrades to “no early truncate”, not a crash, but it is not logged.
  • A legacy v1 connection to the same database is opened at startup and never closed in production; a late write from it can recreate WAL frames after the checkpoint. Not addressed here.
  • Timings were taken on a host at loadavg ~5.5; treat them as indicative.
Workaround on released versions
sqlite3 ~/.minimax/v2/sqlite/runtime-state.sqlite "PRAGMA wal_checkpoint(TRUNCATE);"

after exiting mcode.

Before submitting
  • I have searched existing issues.
  • I have included my version and removed sensitive information.
Vorherrschende Sprache
TypeScript
Sterne
2k
Forks
259
Ø Merge
11 Std.
Gemergte PRs (30 T.)
81

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus MiniMax-AI/minimax-code

Alle Issues in MiniMax-AI/minimax-code

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.