Hi, I spent some time digging deeper into the KnownAssignedXids logic in procarray.c and made a few refinements. Below are some observations and questions I’d like to discuss.
1) Present usage (AFAICS) It appears that logical decoding is the only place that waits for an XID on a standby. The single call-site is SnapBuildWaitSnapshot(), which waits in a simple loop: for (off = 0; off < running->xcnt; off++) { TransactionId xid = running->xids[off]; if (TransactionIdIsCurrentTransactionId(xid)) elog(ERROR, "waiting for ourselves"); if (TransactionIdFollows(xid, cutoff)) continue; XactLockTableWait(xid, NULL, NULL, XLTW_None); } So each backend seems to block on one XID at a time. 2) Picking the waiter data structure Given that behaviour, the total number of concurrent waits can’t exceed MaxBackends. If logical-slot creation stays the primary consumer for now and for future, I’m wondering whether a simple fixed-size array (or even a single global ConditionVariable) might be sufficient. In the patch I currently size the hash table the same as KnownAssignedXids (TOTAL_MAX_CACHED_SUBXIDS), but that may well be conservative. 3) Some trims I’ve removed WakeAllXidWaiters() and call WakeXidWaiters() at each point where an XID is deleted from KnownAssignedXids. Feedback would be much appreciated. Best, Xuneng
v6-0001-Replace-polling-with-waiting-in-XactLockTableWait.patch
Description: Binary data