fix(storage): quarantine bloated HNSW link payloads - #1339
Conversation
|
Threshold 10× checks out empirically against the data from #1218: the crashed palace ran at ~314 (24 GB / 76 MB), healthy snapshots stayed ~0.005 (88 KB / 17.4 MB at 49K drawers). Four orders of magnitude between corruption and any plausible healthy ratio I've seen. The bypass of the mtime gate when If a reproducer fixture would help, I still have the corrupted palace (~6 GB compressed, |
|
Thanks @moonn1000 for validating the threshold and for the detailed data — super helpful. Good to know the mtime bypass matches the real failure case you saw. And yeah, a reproducer could definitely be useful for future regression testing — I’d be in favor of including it if maintainers are open to it. |
|
@fatkobra @jphein — quick re-ping on the reproducer offer. Tarball is still on hand for the corrupted palace from #1218 (the
Compressed size ~6 GB (the link_lists payload is mostly zero-padded so it compresses well). Just need a destination preference from a maintainer:
Happy to also strip it down further (e.g., truncate Also worth knowing: I just hit a separate |
Two conflicts, both because MemPalace#1339 (bloated link payloads) merged into develop after this branch was authored: - mempalace/backends/chroma.py: _segment_appears_healthy now stacks three checks — bloated-link from MemPalace#1339 (top), missing-metadata-with- data-floor from this branch (middle), pickle format sniff (bottom). All three are complementary; MemPalace#1339 catches structural payload corruption, this branch catches pickle truncation, the original catches pickle protocol-byte corruption. - tests/test_backends.py: kept both new imports (_segment_appears_healthy from this branch, quarantine_invalid_hnsw_metadata from MemPalace#1285). Local: 1618 tests pass, ruff lint+format clean against 0.4.x CI pin.
What does this PR do?
Fixes #1218.
This extends the pre-open HNSW health gate so MemPalace quarantines structurally corrupt HNSW segments where
link_lists.binis wildly larger thandata_level0.bin, even whenindex_metadata.picklelooks valid.What changed
link_lists.bin / data_level0.bin10xas corrupt_segment_appears_healthy()so a valid pickle alone is no longer enough to mark a segment healthy.quarantine_stale_hnsw()so link-payload corruption is not blocked by the mtime gate.link_lists.binwith a valid pickleWhy
The latest #1218 investigation found a false negative in the existing HNSW sniff-test:
index_metadata.picklewas structurally validlink_lists.binhad exploded relative todata_level0.binThe old gate answered only “does the pickle look complete?” This PR also asks “does the HNSW payload next to it look physically sane?”
That matters because
ChromaBackend._prepare_palace_for_open()runsquarantine_stale_hnsw()before constructing a Chroma client. By catching the bloated payload there, MemPalace can rename the unsafe segment before Chroma's native HNSW reader has a chance to crash the process.Threshold
The threshold is intentionally conservative: