Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

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

Abierto
#505 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
74/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
sqlite, typescript
Área
database

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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.
Lenguaje dominante
TypeScript
Estrellas
2k
Forks
259
Merge medio
7 h 56 min
PR fusionados (30 d)
126

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de MiniMax-AI/minimax-code

Todos los issues de MiniMax-AI/minimax-code

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.