| From: | "Joel Jacobson" <joel(at)compiler(dot)org> |
|---|---|
| To: | "Arseniy Mukhin" <arseniy(dot)mukhin(dot)dev(at)gmail(dot)com> |
| Cc: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: Optimize LISTEN/NOTIFY |
| Date: | 2025-11-12 20:37:51 |
| Message-ID: | 074cfe3f-b59f-4c42-8dab-f845f691ae0e@app.fastmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Wed, Nov 12, 2025, at 17:57, Arseniy Mukhin wrote:
> On Tue, Nov 11, 2025 at 7:35 PM Joel Jacobson <joel(at)compiler(dot)org> wrote:
>> I'm therefore attaching v24 again, but renamed to v26.
>
> Thank you for the new version!
Thanks for reviewing!
> I read direct advancement part of v26, one point about it:
>
> The comment in SignalBackend says:
>
> * Listening backends that are not advancing and are stationary at
> * a position somewhere in the range we just wrote, can safely be
> * direct advanced to the new queue head, since we know that they
> * are not interested in our messages.
> */
>
> IIUC it's impossible for the listener to stop somewhere in between
> queueHeadBeforeWrite and queueHeadAfterWrite. If the listener has
> managed to read the first notification from the notifier, it means the
> notifier transaction is complete and the listener should stop only
> after reading all notifications (so we should always see pos =
> queueHeadAfterWrite or further).
Here is what I think can happen:
If the notifications written by the notifier fills the current page,
it updates QUEUE_HEAD, and if a listening backend then
enters asyncQueueReadAllNotifications at this time,
it will set its local `head` variable to the current QUEUE_HEAD,
and when the notifier continues filling the next page,
it will again update QUEUE_HEAD, and PreCommit_Notify
will overwrite queueHeadAfterWrite with the QUEUE_HEAD.
Sequence of events:
1. In the notifier, PreCommit_Notify calls asyncQueueAddEntries,
which updates QUEUE_HEAD when the page is full,
(and sets queueHeadAfterWrite to this value).
2. At this time, a listener wakes up and asyncQueueAddEntries
reads the current QUEUE_HEAD value and stores it
in its local `head` variable, and starts reading up to this pos.
3. In the notifier, PreCommit_Notify calls asyncQueueAddEntries
the second time, which updates QUEUE_HEAD,
and sets queueHeadAfterWrite to the final value
before returning.
For this reason, I think the listener could actually stop
in between queueHeadBeforeWrite and queueHeadAfterWrite,
since it's local `head` variable could get the intermediary
QUEUE_HEAD value, when a page is full.
/Joel
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Melanie Plageman | 2025-11-12 20:44:14 | Re: Trying out read streams in pgvector (an extension) |
| Previous Message | Nathan Bossart | 2025-11-12 20:10:16 | Re: another autovacuum scheduling thread |