REINDEX on vchordrq fails with "missing chunk ... for toast value" after 0.5.3 -> 1.0.0 upgrade, when table has dead tuples

Open
#470 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
postgresql, rust
Domain
databases

Research direction

No source file or test is named. Start by reproducing the upgrade sequence with a TOASTed vector column, dead tuples, and the vchordrq index, then compare REINDEX INDEX clip_index with and without VACUUM (ANALYZE) before ALTER EXTENSION vchord UPDATE. Done means the upgraded index can be reindexed successfully without requiring a pre-upgrade vacuum, while the reported TOAST error remains covered by a regression test.

Written by the indexing model from the issue text.

Description

Summary

REINDEX INDEX on a vchordrq index fails with missing chunk number N for toast value M in pg_toast_X after upgrading from 0.5.3 to 1.0.0, when the underlying table has dead tuples. The embeddings themselves are not corrupt — every row detoasts fine and the same reindex succeeds on 0.5.3. Running VACUUM on the table before the extension upgrade avoids the failure entirely.

Environment

  • PostgreSQL 16.14 (Debian 16.14-1.pgdg13+1), Debian 13 (trixie), amd64
  • vchord 0.5.3 → 1.0.0
  • vector (pgvector) 0.8.1 → 0.8.2
  • Table with a TOASTed vector column and a vchordrq index:
    Table "public.smart_search"
      Column   |     Type     | Storage
    -----------+--------------+----------
     assetId   | uuid         | plain
     embedding | vector(1152) | external
    
    Indexes:
        "smart_search_pkey" PRIMARY KEY, btree ("assetId")
        "clip_index" vchordrq (embedding vector_cosine_ops) WITH (
            residual_quantization = false,
            build.internal.lists = [512],
            spherical_centroids = true,
            build_threads = 4,
            sampling_factor = 1024)
    
    ~270k rows.

Steps to reproduce

  1. On vchord 0.5.3, have a table like the above with some accumulated dead tuples (normal insert/update churn without a recent vacuum/autovacuum pass).
  2. Install vchord 1.0.0, restart postgres, then run:
    ALTER EXTENSION vector UPDATE;
    ALTER EXTENSION vchord UPDATE;
    REINDEX INDEX clip_index;
    
  3. Observe the reindex fail partway through clustering:
    INFO:  clustering: estimated memory usage is 2.26 GiB
    ERROR:  missing chunk number 0 for toast value 5517461 in pg_toast_17330
    

What we ruled out

  • Not corrupt data. A full scan of every row (SELECT embedding FROM smart_search per row, forcing detoast) completes with zero failures, both before and after the reported error.
  • Not a fluke. Reproduced deterministically from an identical snapshot: same starting DB restored twice, reindex fails every time without a prior vacuum, and succeeds every time with one. The toast value/chunk number differs slightly between runs (5517461/chunk 0, 5517449/chunk 1 in our tests), consistent with it pointing at whichever dead tuples happen to be present rather than a single fixed corrupt row.

Workaround

Running this before ALTER EXTENSION vchord UPDATE (i.e. still on 0.5.3) reliably prevents the failure:

VACUUM (ANALYZE) smart_search;

Note the ordering matters and there's a bit of a catch-22: if you vacuum after the extension is already on 1.0.0 (with the index still in 0.5.3's on-disk format), VACUUM itself errors out:

ERROR:  deserialization: bad version number; after upgrading VectorChord, please use REINDEX

So recovery has to happen in this order: vacuum while still on the old version → upgrade → reindex.

Expected behavior

REINDEX (or the upgrade path in general) shouldn't fail due to ordinary dead tuples in the heap — index builds normally tolerate this via the visibility map / MVCC snapshot rather than needing every dead row's TOAST data to still be intact. This came up via the Immich community-scripts LXC installer, where several users hit it on the 0.5.3 → 1.0.0 bump (community-scripts/ProxmoxVE#15588) and initially assumed it meant DB corruption.

Dominant language
Rust
Stars
1.8k
Forks
72
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from supervc-stack/VectorChord

All issues in supervc-stack/VectorChord

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.