citusdata / citusdata/citus

PG19: reject distributed REPACK CONCURRENTLY before exclusive lock wait

Open
#8,756 1 comment 0 reactions 0 assignees View on GitHub
pg19_features
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.