Re: LISTEN/NOTIFY bug: VACUUM sets frozenxid past a xid in async queue
Masahiko Sawada <sawada.mshk@gmail.com>
From: Masahiko Sawada <sawada.mshk@gmail.com>
To: Matheus Alcantara <matheusssilv97@gmail.com>
Cc: Arseniy Mukhin <arseniy.mukhin.dev@gmail.com>, Rishu Bagga <rishu.postgres@gmail.com>, Yura Sokolov <y.sokolov@postgrespro.ru>, Daniil Davydov <3danissimo@gmail.com>, Álvaro Herrera <alvherre@kurilemu.de>, Alexandra Wang <alexandra.wang.oss@gmail.com>, PostgreSQL Hackers <pgsql-hackers@postgresql.org>, Tom Lane <tgl@sss.pgh.pa.us>, Joel Jacobson <joel@compiler.org>
Date: 2025-09-15T17:40:40Z
Lists: pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Clear 'xid' in dummy async notify entries written to fill up pages
- 84f1bf4afa5e 14.21 landed
- 21a9014cf00a 15.16 landed
- 0e8eaa2181d4 16.12 landed
- d80d5f099502 17.8 landed
- 82fa6b78dba1 18.2 landed
- 0bdc777e8007 19 (unreleased) landed
-
Fix remaining race condition with CLOG truncation and LISTEN/NOTIFY
- c2e58c0711fe 14.21 landed
- 0c862646cf2a 15.16 landed
- 44e8c60be66c 16.12 landed
- c2682810ab7d 17.8 landed
- 7b069a1876e4 18.2 landed
- 797e9ea6e54b 19 (unreleased) landed
-
Fix bug where we truncated CLOG that was still needed by LISTEN/NOTIFY
- eba917d360e7 14.21 landed
- 1a469d7b5b7d 15.16 landed
- 053e1868b7ee 16.12 landed
- d02c03ddc5e3 17.8 landed
- 321ec54625fd 18.2 landed
- 8eeb4a0f7c06 19 (unreleased) landed
-
Escalate ERRORs during async notify processing to FATAL
- 7cb05dd2d198 14.21 landed
- b1da37de21d4 15.16 landed
- c1a5bde003b8 16.12 landed
- b821c92920f0 17.8 landed
- aab4a84bb070 18.2 landed
- 1b4699090eaf 19 (unreleased) landed
-
Limit the size of TID lists during parallel GIN build
- c98dffcb7c70 19 (unreleased) cited
On Sat, Sep 6, 2025 at 7:15 AM Matheus Alcantara <matheusssilv97@gmail.com> wrote: > > On Fri Sep 5, 2025 at 9:56 AM -03, Arseniy Mukhin wrote: > >> Ok, I agree that that this may happen but I don't see this as a common > >> case to fix the issue based on this behaviour. I think that we check the > >> transaction status also to skip notifications that were added on the > >> queue by transactions that are not fully committed yet, and I see this > >> scenario as a more common case but I could be wrong. > >> > > > > IIUC we don't need clog to check if the notification transaction is > > still in progress, we use a snapshot for that (XidInMVCCSnapshot()). > > If we see that the notification transaction is still in progress, we > > postpone processing of that notification. If we see that notification > > transaction is not in progress, then we check its status with > > TransactionIdDidCommit() (using clog) and only then fail if clog > > doesn't have notification transcation data (as a quick check, we can > > see in the stack trace that the failure occurs during the call to > > TransactionIdDidCommit, not XidInMVCCSnapshot). > > > > So we need to check notification transaction status only to understand > > if a transaction was committed and we can send notification or it was > > aborted (somewhere in between PreCommit_Notify and AtCommit_Notify) > > and we should skip notification. And the solution that Yura Sokolov > > suggested is to introduce a 'commited' flag, so we can check it > > instead of calling TransactionIdDidCommit. Another option is to make > > aborted transactions to clean up after themselves in AtAbort_Notify(), > > so if listener see notification in the queue and transaction that > > wrote it is not in progress, then such notification was always created > > by committed transaction and we also don't need to call > > TransactionIdDidCommit. One way for aborted transactions to clean up > > is to set its notifications dbOid to 0, so listeners skip them. > > Another option I think is to set queue HEAD back to the position where > > it was when the aborted transaction started to write to the queue. It > > also makes such aborted transaction notifications 'invisible' for > > listeners. We have a global lock and there is always only one writer, > > so it sounds possible. And there is another option which is the patch > > that Rishu Bagga is working on. In the patch all transactions write to > > the listen/notify queue only after they wrote a commit record to the > > WAL, so all notifications in the queue are always by committed > > transactions and we don't need to call TransactionIdDidCommit. > > > You are right, I missed the XidInMVCCSnapshot() call, sorry about that > and thanks very much for all the explanation! > > I'll keep on hold the development of new patch versions for this thread > and focus on review and test the patch from Rishu at [1] to see if we > can make progress using the WAL approach. While the WAL-based approach discussed on another thread is promising, I think it would not be acceptable for back branches as it requires quite a lot of refactoring. Given that this is a long-standing bug in listen/notify, I think we can continue discussing how to fix the issue on backbranches on this thread. Regards, -- Masahiko Sawada Amazon Web Services: https://aws.amazon.com