PG19: reject distributed REPACK CONCURRENTLY before exclusive lock wait
- Dominant language
- C
- Stars
- 12.8k
- Forks
- 794
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 31
Description
## Problem
Citus intentionally does not support distributed `REPACK (CONCURRENTLY)` on PostgreSQL 19, and existing tests verify the clear unsupported error and unchanged shard relfilenodes.
However, Citus currently resolves the target relation with `AccessExclusiveLock` before checking whether `CONCURRENTLY` is enabled. If another session holds only `AccessShareLock`, the command waits or times out on the exclusive lock instead of promptly returning the intended unsupported-feature error.
## Verified behavior
On PG19 Beta 2:
- Uncontended `REPACK (CONCURRENTLY)` returns the expected unsupported error and creates no repack replication slots.
- With a concurrent reader holding `AccessShareLock`, Citus blocks waiting for `AccessExclusiveLock`; the unsupported error is masked.
## Scope
This issue does **not** add distributed concurrent REPACK support. Real support requires placement-level deparsing, transaction restart, placement/colocation coordination, slot and background-worker budgeting, and non-atomic partial-failure semantics.
## Proposed minimum fix
- Detect enabled `CONCURRENTLY` before target lookup.
- Resolve the target using PostgreSQL core's compatible `ShareUpdateExclusiveLock` for this rejection path.
- Preserve the current `IsCitusTable()` check, then reject before partition/local/worker processing.
- Keep ordinary REPACK/CLUSTER locking unchanged.
## Acceptance criteria
- A second session holding `AccessShareLock` cannot mask the distributed unsupported error.
- No shard DDL or relfilenode change occurs.
- No `pg_repack_*` replication slot is created.
- Existing explicit-transaction and ordinary REPACK tests continue to pass.
- Add PG19-only concurrent-session regression coverage for the reader-lock case.
## Future work
Distributed `REPACK (CONCURRENTLY)` support remains a separate design project. A conservative first implementation would serialize the operation, limit one active placement per node, preflight `max_repack_replication_slots`, WAL level, and worker capacity, and document non-atomic retry semantics.
Contributor guide
Research direction
Locate the existing REPACK/CLUSTER locking and unsupported-error tests, including explicit-transaction and ordinary REPACK coverage, then trace target lookup before the CONCURRENTLY check. Add PG19-only concurrent-session regression coverage for a reader holding AccessShareLock; done means the unsupported error is prompt, with no shard DDL, relfilenode change, or pg_repack_* replication slot, while existing tests pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, postgresql
- Domain
- databases, distributed-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100