Re: Possible G2-item at SERIALIZABLE - Mailing list pgsql-bugs

From Andrey Borodin
Subject Re: Possible G2-item at SERIALIZABLE
Date
Msg-id 787936C5-4155-4CF9-939D-39DC0EC1C892@yandex-team.ru
Whole thread
In response to Re: Possible G2-item at SERIALIZABLE  (Andrey Borodin <x4mmm@yandex-team.ru>)
List pgsql-bugs

> On 1 Jun 2026, at 11:18, Andrey Borodin <x4mmm@yandex-team.ru> wrote:
>
> There's a separate case

Two more SSI false-negatives in the same area, found by Nik's machines
and Mark-bot while triaging original report.

INSERT ... ON CONFLICT reads the conflicting ("arbiter") row to decide
what to do, but doesn't take an SIREAD predicate lock on it. So when
the statement ultimately writes no tuple, that read leaves no trace for
SSI and a concurrent modification of the same row can produce a
non-serializable all-commit result:
 * ON CONFLICT DO UPDATE ... WHERE <false> — the no-op update branch; the
   conflict row is observed but not updated.
 * ON CONFLICT DO NOTHING with a concurrent DELETE of the conflict row.

Replacing the ON CONFLICT with a plain SELECT of the same row aborts
correctly, which is what convinced me the schedules are genuinely
non-serializable and the gap is in the ON CONFLICT probe path.

Both come from the same place - check_exclusion_or_unique_constraint() in
execIndexing.c finds the arbiter tuple but never calls PredicateLockTID().
Adding that lock there fixes both.


There's also one more false negative, but it is in -DTEST_SUMMARIZE_SERIAL
and IMO worth working only when we deal with what we have in production
cases.


Best regards, Andrey Borodin.


Attachment

pgsql-bugs by date:

Previous
From: Andrey Borodin
Date:
Subject: Re: Possible G2-item at SERIALIZABLE
Next
From: Álvaro Herrera
Date:
Subject: Re: BUG #19500: pgrepack logical decoding plugin can crash assert builds via SQL decoding API