Re: Partitioned index marked valid while a partition is pending detach

From: Michael Paquier <michael(at)paquier(dot)xyz>
To: shihao zhong <zhong950419(at)gmail(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Álvaro Herrera <alvherre(at)kurilemu(dot)de>
Subject: Re: Partitioned index marked valid while a partition is pending detach
Date: 2026-11-05 01:32:26
Message-ID: auvcqu52oopT6ToW@paquier.xyz
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, Nov 03, 2026 at 09:46:35PM -0500, shihao zhong wrote:
> A partitioned unique index can be marked valid while one partition has
> no index. That partition then accepts duplicate keys.
>
> In another session, open a transaction and read from t. Run "alter
> table t detach partition p1 concurrently". It waits for that
> transaction. Cancel it, and p1 stays pending detach. Then:
>
> alter index ti attach partition p2_a;
>
> Now ti is valid, but p3 has no index.

Obviously that's wrong. indisvalid on a partitioned index should only
be switched to true if all its partition indexes are valid. If a
partitioned table has an index but no partitions, the flag could be
true.

> validatePartitionedIndex() marks ti valid once it has as many valid
> child indexes as t has partitions. It sees two child indexes, p1_a and
> p2_a. It also sees two partitions, p2 and p3. It skips p1 because p1 is
> pending detach. So two equals two and ti becomes valid, even though p3
> has no index.
>
> So we just need a one liner fix which is use false to count all partitions.
> 0001 is the fix and 0002 is the test on the existing detach test.

Yeah, I think that you are right here. I was wondering if the test
should be simplified a bit, without a third partition, but what you
are doing may be cleaner overall. The last "s2detachfinal s1valid"
steps in the new permutation don't seem strongly necessary if you want
to check your case. Or do you specifically want to have coverage of a
FINALIZE with an attached index? I would cut these two steps, just
wondering if you have an argument in favor of keeping them.

On top of that, indexcmds.c uses RelationGetPartitionDesc(true) as
well. Could that be a source of problems when creating a unique index
on a partitioned table, for example? It also looks like we could
finish with a broken unique constraint with duplicated data inserted
due to a miscount of the number of partitions, with a indisflag marked
as valid when we should not mark it as such? Perhaps this should have
a separate investigation.
--
Michael

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Keyerror Smart 2026-11-05 01:38:49 Re: [PATCH]Fix planner's strictness check for JsonExpr
Previous Message Sami Imseih 2026-11-05 01:08:54 Re: pgstat: Flush some statistics within running transactions, take 2