feat(optimize): surface vector index layout so coverage answers can-it-prune - #532
feat(optimize): surface vector index layout so coverage answers can-it-prune#532memmmmike wants to merge 1 commit into
Conversation
…t-prune A mono-partition IVF index over a large table reports complete coverage while every nearest() reads the full index payload; delta optimize_indices folds never re-partition, so the state is invisible to anyone watching coverage (issue ModernRelay#486, from the ModernRelay#432 production incident). optimize stats now carry a VectorIndexLayout per built vector index: index name, partition summary, indexed rows, worst rows-per-partition across delta segments, and a degenerate flag. The flag is computed PER SEGMENT (Lance searches delta segments independently, so a well-partitioned later segment cannot repair a bad earlier one) from rows-per-partition, which catches both the mono-partition case and the incident's own 8-partitions-over-852k-rows shape. The CLI prints layouts under each table and marks degenerate ones loudly; --json carries the full struct. Statistics missing the expected fields are a loud error, not a silent skip, and lance_surface_guards now pins num_indexed_rows and num_indexed_rows_per_delta alongside num_partitions. Reporting only: the repair itself remains ModernRelay#485. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E4S9Xpe9G7pLEv9JaoXUAb
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
| "vector_index_layouts": s.vector_index_layouts.iter().map(|v| serde_json::json!({ | ||
| "column": v.column, | ||
| "index_name": v.index_name, | ||
| "partitions": v.partitions, | ||
| "indexed_rows": v.indexed_rows, | ||
| "max_rows_per_partition": v.max_rows_per_partition, | ||
| "degenerate": v.degenerate, | ||
| })).collect::<Vec<_>>(), |
There was a problem hiding this comment.
optimize --json now emits vector_index_layouts, and the human output reports healthy and degenerate layouts, but the maintenance documentation still enumerates the old field set. Update docs/user/operations/maintenance.md in this PR so operators and JSON consumers can discover the new layout, partition, and degeneracy fields.
Context Used: CLAUDE.md (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Resolves #486.
Coverage currently answers "does an index exist over these rows" but not "can it prune" — the exact blindspot from the #432 incident, where
pending_indexes: []reported a healthy index while everynearest()flat-read ~10 GB.What this adds (reporting only; the repair remains #485):
TableOptimizeStats.vector_index_layouts: per built vector index — name, partition summary, indexed rows, worst rows-per-partition across delta segments, and adegenerateflag.--jsoncarries the full struct.lance_surface_guardsnow pinsnum_indexed_rowsandnum_indexed_rows_per_delta(aligned withindices[]) beside the existingnum_partitionspin, so a Lance upgrade that changes the shape fails the guard instead of degrading the stats.Scope checked:
skipped_for_driftintentionally reports no layout (that HEAD is not manifest-accepted);TableOptimizeStatsis not serialized by the server, so no OpenAPI drift.Tests: classifier unit tests including the incident shape and the bad-segment-behind-good-segment case; an end-to-end maintenance test asserting layouts surface through
optimize()on a real vector index; the guard pins. Maintenance suite 34/34. CLI smoke on a local graph verified both text and--jsonoutput, and a no-vector-column graph stays clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01E4S9Xpe9G7pLEv9JaoXUAb
Greptile Summary
The PR exposes physical vector-index layouts through optimize statistics and CLI output so operators can distinguish index coverage from effective pruning.
Confidence Score: 4/5
The PR appears safe to merge after the non-blocking optimize documentation mismatch is corrected.
The changed snapshot flow refreshes layout statistics after index effects, and no current runtime or compatibility defect was established; the remaining issue is that the documented optimize output omits the newly emitted layout fields.
Files Needing Attention: crates/omnigraph-cli/src/main.rs and docs/user/operations/maintenance.md
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR A[Lance index_statistics] --> B[TableStore parser] B --> C[Per-segment partitions and rows] C --> D[VectorIndexLayout classifier] D --> E[TableOptimizeStats] E --> F[CLI text output] E --> G[CLI JSON output]Reviews (1): Last reviewed commit: "feat(optimize): surface vector index lay..." | Re-trigger Greptile
Context used: