revert #000067 phase-2 page_size=16384 — measured worse than default

3090 bench-max v3 run at 13:25 elapsed had shards at 696-760 MB; v2
at 8:46 elapsed (default 4 KB pages) had 549-662 MB. Larger pages
made the chunk-content UPDATE workload SLOWER, not faster.

Reason: chunk-content payloads average ~500 bytes after zstd. With
4 KB pages each UPDATE rewrites a 4 KB page; with 16 KB pages the
same UPDATE rewrites a 16 KB page → 4× write amplification per
row. ext4 journal traffic increases roughly proportionally.

Bigger pages help SCAN-heavy workloads (fewer page reads to walk
a B-tree). For narrow-row-UPDATE-heavy workloads like cold-pack
chunk fill, they hurt. Comment in code captures the measurement
so a future operator doesn't re-attempt this.

The other bench-max measures stay in place:
  - synchronous = OFF                 (per-write fsync removed)
  - journal_mode = MEMORY             (WAL in RAM)
  - temp_store = MEMORY               (sort scratch in RAM)
  - cache_size = -524288              (512 MB page cache)
  - mmap_size = 536870912             (512 MB read mmap)
  - foreign_keys = OFF                (no FK verify per row)
  - deferred FTS5 rebuild post-pass
  - batched 5000-row executemany UPDATEs
  - bench-max #5 (this commit's revert): page_size stays at 4 KB

Next bench point: v4 against the new bucket packs that include
fts (--include-fts producer run in flight). That eliminates the
FTS rebuild step entirely on the consumer.
This commit is contained in:
russell@unturf.com 2026-05-26 19:39:16 -04:00
parent da1a355df4
commit e409a30a40
No known key found for this signature in database

View file

@ -2995,29 +2995,16 @@ def _cmd_cold_unpack(args: argparse.Namespace) -> int:
# directory; --hydrate-M picks the routing modulus. Each incoming
# row lands on shard_for_document(root, M).
if args.hydrate_shards_dir:
import sqlite3
target_dir = Path(args.hydrate_shards_dir).expanduser()
target_dir.mkdir(parents=True, exist_ok=True)
M = args.hydrate_M
target_paths = [target_dir / f"{i:03d}.db" for i in range(M)]
# #000067 bench-max: bump page_size before schema applies so the
# corpus uses 16 KB pages instead of SQLite's 4 KB default.
# Bigger pages → ~4× fewer page writes during chunk-fill →
# ~4× fewer ext4 metadata journal events (jbd2_log_wait_commit
# was the measured bottleneck on the 3090). page_size CAN ONLY
# be set on an empty DB; VACUUM finalises it. Idempotent on
# re-runs since fresh hydrate dirs are clean.
for p in target_paths:
if not p.exists() or p.stat().st_size == 0:
pre = sqlite3.connect(str(p))
try:
pre.execute("PRAGMA page_size = 16384")
pre.execute("PRAGMA secure_delete = OFF")
pre.execute("VACUUM") # commit the page_size change
finally:
pre.close()
# NOTE: I tried PRAGMA page_size = 16384 on hydrate targets
# to reduce ext4-journal contention by emitting fewer
# page-write events. Measured WORSE on 2026-05-26 — narrow
# UPDATEs (~500 byte content per row) rewrite the whole
# page; 16 KB pages = 4× write amplification per chunk-
# content UPDATE. Stay at SQLite default 4 KB.
targets: list = []
for p in target_paths:
t = connect(p)