| From: | Alexander Korotkov <aekorotkov(at)gmail(dot)com> |
|---|---|
| To: | Sami Imseih <samimseih(dot)pg(at)gmail(dot)com> |
| Cc: | Xuneng Zhou <xunengzhou(at)gmail(dot)com>, Álvaro Herrera <alvherre(at)kurilemu(dot)de>, Postgres hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Reject WAIT FOR earlier in transaction-snapshot mode |
| Date: | 2026-09-17 20:52:09 |
| Message-ID: | CAPpHfdstCVxb-iXsqjZ2umJQdzFud4fypZRCVEZnEOTLyp0gGw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Thu, Sep 17, 2026 at 5:53 PM Sami Imseih <samimseih(dot)pg(at)gmail(dot)com> wrote:
>
> > > Done in v6.
> >
> > Xuneng, Sami, do you think v6 is good enough?
>
> I think the user-facing documentation can be simplified considerably while
> preserving the important information. I prefer the below changes on top
> of v6:
>
> 1/ State directly that WAIT cannot be executed while the current transaction
> holds a snapshot.
> 2/ Clarify that WAIT itself does not acquire a snapshot.
> 3/ Explain that it can therefore be executed before the first snapshot-taking
> statement in a REPEATABLE READ or SERIALIZABLE transaction.
> 4/ Briefly explain why holding a snapshot can prevent a standby wait from
> completing.
>
>
> ```
> <command>DO</command> block. It also cannot be executed while the
> - current transaction holds a snapshot. A transaction running at an
> - isolation level higher than <literal>READ COMMITTED</literal> holds one
> - from its first query until it ends, so <command>WAIT</command> is
> - accepted before that query and rejected after it. An open cursor or an
> - exported snapshot has the same effect at any isolation level.
> - </para>
> -
> - <para>
> - The restriction above exists because such a snapshot could stand in
> - the way of the very replay being waited for: replaying a record that
> - removes rows the snapshot can still see raises a recovery conflict.
> - This conflict could be resolved by delaying the replay or by cancelling
> - this session. Having to run without a snapshot is also the reason why
> - <command>WAIT</command> is a command rather than a function or a procedure,
> - which execute with one held.
> - </para>
> -
> - <para>
> - The other standby modes are not independent of replay either, even though
> - they do not wait for it directly. Their positions advance as WAL arrives,
> - but WAL is recycled only at restartpoints, and a restartpoint cannot be
> - created past a checkpoint record that replay has not reached. While
> - replay is held back, <filename>pg_wal</filename> therefore keeps growing
> - past <xref linkend="guc-max-wal-size"/>, and reception stops once the file
> - system fills.
> + current transaction holds a snapshot.
> + <command>WAIT</command> itself does not acquire a snapshot, so it can be
> + executed before the first snapshot-taking statement in a
> + <literal>REPEATABLE READ</literal> or <literal>SERIALIZABLE</literal>
> + transaction. Holding a snapshot while using a standby wait mode could
> + delay WAL replay and prevent the wait from completing.
> </para>
> ```
Agreed. v7 attached: three paragraphs collapsed into one, close to your
wording. I kept three bits from v6:
* mention the cursor and the exported snapshot as those who may hold snapshots;
* "which standby_replay waits for and the other standby modes
ultimately depend on", so that write and flush are not read as exempt;
* "that is also why WAIT is a command rather than a function or a
procedure", which makes the restriction in the first sentence follow
from the same rule instead of looking arbitrary.
------
Regards,
Alexander Korotkov
Supabase
| Attachment | Content-Type | Size |
|---|---|---|
| v7-0001-Say-what-WAIT-s-snapshot-restriction-actually-is.patch | application/octet-stream | 6.4 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | David Rowley | 2026-09-17 20:55:38 | Re: RANGE partition pruning can still exclude the default partition |
| Previous Message | Álvaro Rodríguez | 2026-09-17 20:25:35 | Re: Unexpected reindex when altering column types for partitioned tables |