Problem: https://github.com/bitcoin-core/leveldb-subtree/pull/61 disabled read-triggered seek compactions to avoid large chainstate write amplification from random UTXO lookups. That avoids repeated read-driven rewrites, but it also removes opportunistic cleanup that previously helped compact old chainstate data.
After IBD, normal chainstate churn can leave obsolete entries behind until ordinary LevelDB compaction naturally reaches the affected levels, keeping the chainstate database larger than necessary.
Also, chainstates created by pre-29 nodes can contain thousands of files from the old 2 MiB LevelDB table target. After the mmap limit dropped back to 1000 and seek compaction was disabled, continuing from such a chainstate can leave many table reads on the non-mmap path until the database is compacted.
Fix: After each completed post-IBD full chainstate flush, give the chainstate a 1/320 chance to compact. With roughly hourly full flushes, this averages about once every two weeks and makes a six-month stretch without compaction about a one-in-a-million event.
The randomized recurring trigger spreads compactions across nodes and keeps maintenance stateless, without storing last-compaction height or timestamp metadata in the chainstate database.
Compaction runs on a background thread (utxocompact) so validation only schedules the work.