Re: LISTEN/NOTIFY bug: VACUUM sets frozenxid past a xid in async queue

Álvaro Herrera <alvherre@kurilemu.de>

From: Álvaro Herrera <alvherre@kurilemu.de>
To: Heikki Linnakangas <hlinnaka@iki.fi>
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>, pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2025-11-07T14:14:31Z
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 →
  1. Clear 'xid' in dummy async notify entries written to fill up pages

  2. Fix remaining race condition with CLOG truncation and LISTEN/NOTIFY

  3. Fix bug where we truncated CLOG that was still needed by LISTEN/NOTIFY

  4. Escalate ERRORs during async notify processing to FATAL

  5. Limit the size of TID lists during parallel GIN build

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.)


-- 
Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
"I'm always right, but sometimes I'm more right than other times."
                                                  (Linus Torvalds)
https://lore.kernel.org/git/Pine.LNX.4.58.0504150753440.7211@ppc970.osdl.org/