From a7bdbea9fdbfe4d24e0e971ebfab20d854a2ca44 Mon Sep 17 00:00:00 2001 From: Ewan Young Date: Fri, 28 Aug 2026 23:40:01 +0800 Subject: [PATCH v2] Repack: Fix replica identity index check check_concurrent_repack_requirements() obtained the identity index with GetRelationIdentityOrPK(), which falls back to the primary key when there is no replica identity index. Logical decoding, however, uses RelationGetReplicaIndex() and does not fall back to the primary key. So a table with REPLICA IDENTITY USING INDEX whose index has since been dropped (relreplident still 'i', but the index gone) passes the check via the PK fallback, lets the repack start, and then fails during catch-up with "incomplete delete info" once a delete has to be decoded. Use RelationGetReplicaIndex() so the check matches what decoding needs, and keep the existing error structure: the deferrable-primary-key case stays a reason for "no identity index" (inside the !OidIsValid branch). This avoids wrongly rejecting a table that has an explicit replica identity index but no primary key, and keeps the deferrable-specific message for the case it is meant for. --- src/backend/commands/repack.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 477c86b2ba6..cc8c52662be 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -924,13 +924,14 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p) "REPLICA IDENTITY NOTHING" : "REPLICA IDENTITY FULL")); /* - * Obtain the replica identity index -- either one that has been set - * explicitly, or a non-deferrable primary key. If none of these cases - * apply, the table cannot be repacked concurrently. It might be possible - * to have repack work with a FULL replica identity; however that requires - * more work and is not implemented yet. - */ - ident_idx = GetRelationIdentityOrPK(rel); + * Obtain the replica identity index -- the one set explicitly, or the + * default non-deferrable primary key. Use RelationGetReplicaIndex(), not + * GetRelationIdentityOrPK(): decoding does not fall back to the primary + * key, so neither may we. If there is no such index, the table cannot be + * repacked concurrently; a FULL replica identity might be workable but is + * not implemented yet. + */ + ident_idx = RelationGetReplicaIndex(rel); if (!OidIsValid(ident_idx)) { /* This special case warrants its own error message */ -- 2.47.3