Re: LISTEN/NOTIFY bug: VACUUM sets frozenxid past a xid in async queue
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Álvaro Herrera <alvherre@kurilemu.de>, pgsql-hackers <pgsql-hackers@postgresql.org>
Cc: Matheus Alcantara <matheusssilv97@gmail.com>,
Arseniy Mukhin <arseniy.mukhin.dev@gmail.com>,
Joel Jacobson <joel@compiler.org>, Tom Lane <tgl@sss.pgh.pa.us>
Date: 2025-11-12T19:39:47Z
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 07/11/2025 16:14, Álvaro Herrera wrote: > One thing I noticed while testing this is that asyncQueueAddEntries() > fills the end of a page with a dummy entry, when the next notify doesn't > fit. However, this dummy entry contains a very valid TransactionId, > which the new freezing code will try to look up and freeze. I think > this is somewhat bogus -- we shouldn't even try to look up that XID in > the first place. I propose to clear it like this > > @@ -1419,6 +1424,7 @@ asyncQueueAddEntries(ListCell *nextNotify) > */ > qe.length = QUEUE_PAGESIZE - offset; > qe.dboid = InvalidOid; > + qe.xid = InvalidTransactionId; > qe.data[0] = '\0'; /* empty channel */ > qe.data[1] = '\0'; /* empty payload */ > } > > > (Line numbers do not match, because I have other local changes.) Committed. I committed the above separately, because I forgot to include it in the main commit. Oops. Just to summarize what was committed, out of all the different variants discussed: * Any ERROR while processing an async notification is now turned into FATAL * Vacuum scans the async notification queue and freezes xids before truncating CLOG * The TransactionIdDidCommit() calls are now made while holding the SLRU lock. NotifyMyFrontEnd() calls are still made after releasing the lock * listenChannels == NIL special case is checked before TransactionIdDidCommit(). This avoids the problem that no backend can LISTEN to anything anymore, if there's one broken entry in the queue for some reason * 'xid' field on dummy entries is now set to InvalidTransactionId so that they don't need to be frozen Thanks everyone! - Heikki