Skip to content

perf(mvcc): collect Passive checkpoint from pending keys - #9

Closed
pereman2 wants to merge 1 commit into
bench-reclaim-gc-perfstack-20260907from
mvcc-pending-checkpoint-collect
Closed

pereman2 wants to merge 1 commit into
bench-reclaim-gc-perfstack-20260907from
mvcc-pending-checkpoint-collect

Conversation

@pereman2

@pereman2 pereman2 commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Why

Passive checkpoint collect walked every live MvStore.rows / index_rows key each tick. Under load, Rule 3 keeps currents in the SkipMap, so that walk grew with the working set even when almost nothing was still above durable_txid_max. EC2 c=4 profiles showed SkipList::search_bound under collect_table_rows as a real cost beside SQPOLL.

Scope

  • MvStore::checkpoint_pending_{table,index}_rows tagged by commit ts
  • note_checkpoint_pending at Preparing (before last_committed_tx_ts can cover the keys)
  • collect_table_rows / collect_index_rows iterate pending maps and look up chains in the store
  • retire_checkpoint_pending_through after durable watermark publish
  • Recovery seeds pending keys above the replay cutoff
  • Unit test collect_table_rows_skips_rows_not_in_pending_set

Out of scope: io_uring / SQPOLL, Passive write-phase cost that still grows with how much must land in the B-tree.

Tradeoffs

Pending-key set over a timestamp-ordered secondary index. Smaller surface; relies on existing checkpoint_snapshot_ts Preparing floor plus enqueue-before-Committed. Nested by_version maps remain available if out-of-order holes show up in production.

Blast Radius

MVCC Passive and Truncate checkpoint collection and commit prepare. Failed checkpoints keep pending tags. Aborted prepares leave stale tags that collect no-ops and later retire.

Verification

  • cargo test -p turso_core --lib checkpoint_state_machine::tests (16 ok)
  • cargo test -p turso_core --lib mvcc::database::tests::test_checkpoint (24 ok)
  • Same-config EC2 NVMe A/B (i-05fc9cecc91c64a99, tip 744d84a915, c=4, group-commit, checkpointer 1000, 45s):
TPS cpu_us/tx ckpt p50 ckpt max
baseline 1781 2902 1.745s 7.042s
pending 2000 2540 1.422s 3.166s

Artifacts: /mnt/nvme/run/ab-pending-collect-c4-20260907/ and .audit/ab-pending-collect-c4-20260907/summary.txt.

Passive collect walked every live SkipMap key each tick even when
almost nothing was still above durable_txid_max. Under load Rule 3
keeps currents in the map, so that walk grew with the working set.

Enqueue write-set keys while the commit is still Preparing, collect
from those maps, and retire tags only after a durable watermark
publish. Recovery seeds the same maps above the replay cutoff.

Tests: checkpoint_state_machine collect_* unit tests
Measure: EC2 NVMe c=4 A/B tip-gc (45s): TPS 1781→2000, ckpt_max 7.0s→3.2s
@pereman2 pereman2 closed this Sep 14, 2026
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