Skip to content

Fix double constraint creation for tables with EXCLUSION indexes#43

Merged
teknogeek0 merged 1 commit into
mainfrom
fix/exclusion-constraint-double-create
Jul 17, 2026
Merged

Fix double constraint creation for tables with EXCLUSION indexes#43
teknogeek0 merged 1 commit into
mainfrom
fix/exclusion-constraint-double-create

Conversation

@teknogeek0

Copy link
Copy Markdown
Collaborator

Problem

A table with both a PRIMARY KEY (or UNIQUE) index and an EXCLUSION constraint index aborts the clone:

ERROR: index "..._pkey" is already associated with a constraint
indexes.c:453 Failed to create constraints for table ...

summary_table_count_indexes_left excluded EXCLUSION constraint indexes from the "indexes remaining" count. Those indexes are still queued and processed by a worker (which marks them done), so countIndexesLeft reached zero twice for the table and the constraint-creation phase ran twice — the second ALTER TABLE ... ADD CONSTRAINT on the pkey is fatal. It only manifests with --index-jobs 1; with more workers a different PID skips the second pass.

Fix

  • summary_table_count_indexes_left: count all indexes so countIndexesLeft reaches zero exactly once.
  • Defense-in-depth: skip a constraint in copydb_create_constraints when the summary already records a done_time.
  • summary_add_constraint: INSERT OR REPLACEINSERT OR IGNORE, so the second pass can't wipe the done_time set by the first.

Ports upstream dimitri/pgcopydb dimitri#965, adapted to this repo's copydb_create_constraints loop (upstream applies the guard in a per-index hook that doesn't exist here).

Tests

  • tests/unit/17-exclusion-with-pkey — a table with both a PK and an EXCLUSION constraint, verifying both land on the target.
  • tests/unit/script/6-exclusion-constraint-index-jobs.sh — clones with --index-jobs 1 and --index-jobs 4. This reproduces the abort without the fix (verified: unit suite exits non-zero pre-fix with the exact error above, and passes with the fix).

Verified locally: PGVERSION=18 make tests/unit green with the fix; fails pre-fix.

A table with both a PRIMARY KEY (or UNIQUE) index and an EXCLUSION
constraint index aborted the clone with:

  ERROR: index "..._pkey" is already associated with a constraint

summary_table_count_indexes_left excluded EXCLUSION constraint indexes from
the "indexes remaining" count. Those indexes are still queued and processed
by a worker (which marks them done), so countIndexesLeft reached zero twice
for the table and the constraint-creation phase ran twice; the second ALTER
TABLE ADD CONSTRAINT on the pkey was fatal. It only manifested with
--index-jobs 1 — with more workers a different PID skipped the second pass.

Count all indexes so countIndexesLeft reaches zero exactly once. As
defense-in-depth, skip a constraint in copydb_create_constraints when the
summary already records a done_time, and change summary_add_constraint from
INSERT OR REPLACE to INSERT OR IGNORE so the second pass cannot wipe it.

Ports upstream dimitri/pgcopydb dimitri#965. Adds a unit test (table with PK +
EXCLUSION) and an --index-jobs 1 script test that reproduces the abort
without the fix.
@teknogeek0
teknogeek0 merged commit f9f3830 into main Jul 17, 2026
93 checks passed
@teknogeek0
teknogeek0 deleted the fix/exclusion-constraint-double-create branch July 17, 2026 00:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant