Re: tablecmds: fix bug where index rebuild loses replica identity on partitions

From: "Alberto Piai" <alberto(dot)piai(at)gmail(dot)com>
To: "Chao Li" <li(dot)evan(dot)chao(at)gmail(dot)com>, "Postgres hackers" <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Cc: "Xuneng Zhou" <xunengzhou(at)gmail(dot)com>, "Michael Paquier" <michael(at)paquier(dot)xyz>
Subject: Re: tablecmds: fix bug where index rebuild loses replica identity on partitions
Date: 2026-07-22 23:06:56
Message-ID: DK5H6VM4U4J4.C8APP2ZH2CAT@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu Jul 16, 2026 at 4:49 AM CEST, Chao Li wrote:
>>>>>>>>>>>>> On Tue, Jan 27, 2026 at 01:13:32PM +0800, Chao Li wrote:
>>>>>>>>>>>>>> I found this bug while working on a related patch [1].
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> When ALTER TABLE ... ALTER COLUMN TYPE causes an index rebuild, and
>>>>>>>>>>>>>> that index is used as REPLICA IDENTITY on a partitioned table, the
>>>>>>>>>>>>>> replica identity marking on partitions can be silently lost after the
>>>>>>>>>>>>>> rebuild.
>>>>>>>>>>>>>

I was going to review the patch, but I am not sure I understand the root
cause.

I tried to reproduce the problem with inheritance, which I would expect
to behave the same as partitions in this case:

create table p (a int not null, b int not null);
create table c () inherits (p);
create unique index p_b_idx on p(b);
create unique index c_b_idx on c(b);
alter table p replica identity using index p_b_idx;
alter table c replica identity using index c_b_idx;

Surprisingly though, the replica identity is not lost in this case:

alter table p alter b type bigint;

select c.relname as index_name, c.oid as index_oid, i.indisreplident
from pg_class c join pg_index i on c.oid = i.indexrelid
where (c.relname in ('p_b_idx', 'c_b_idx'));

index_name | index_oid | indisreplident
------------+-----------+----------------
p_b_idx | 24773 | t
c_b_idx | 24774 | t

For both inheritance and partitions, RememberAllDependentForRebuilding()
is called twice, first for the parent and then for the child table.

In the inheritance case, RememberAllDependentForRebuilding() finds a
dependency on the respective index both for the parent and the child
table. For each of the indexes, it calls RememberIndexForRebuilding()
which calls RememberReplicaIdentityForRebuilding().

In the partitions case though, RememberAllDependentForRebuilding does
not find a dependency on the index when it gets called on the child
table (partition).

I think what's happening here is that ATPostAlterTypeCleanup()
is invoked on the parent first: it tries to drop the index (which will
be recreated later in phase 3) using performMultipleDeletions(), which
will call findDependentObjects() and drop those too.

For partitions, I see a dependency of type 'P'
(DEPENDENCY_PARTITION_PRI) which is not there for plain inheritance.

select c1.relname as obj_name,
c2.relname as refobj_name,
d.deptype
from pg_depend d
join pg_class c1 on c1.oid = d.objid
join pg_class c2 on c2.oid = d.refobjid
where refobjid = 'part_a_b_idx'::regclass;

obj_name | refobj_name | deptype
-----------------+--------------+---------
part_p1_a_b_idx | part_a_b_idx | P

Could this be the reason why the partition index is being dropped
so early, thus never getting a chance to be recorded as "restore replica
identity"?

Seeing how things work for inheritance, if we could somehow avoid this
drop, the index might be dropped/rebuilt correctly later, when the
command recurses to the child partition.

For completeness, my partitioned setup for the queries above was:

create table part (a int not null, b int not null) partition by list(a);
create table part_p1 partition of part for values in (1);
create unique index part_a_b_idx on part(a, b);
alter table part replica identity using index part_a_b_idx;
alter table part_p1 replica identity using index part_p1_a_b_idx;

Regards,

Alberto

--
Alberto Piai
Sensational AG
Zürich, Switzerland

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Quan Zongliang 2026-07-23 02:23:24 Re: [PATCH] Remove unused include from analyze.c
Previous Message Alberto Piai 2026-07-22 21:19:56 Re: Allow progress tracking of sub-commands