Locks release order in LogStandbySnapshot

Started by Japin Lialmost 4 years ago3 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t46904
psql -h localhost -U postgres

Built from patchset v1 (message #1), September 20, 2026 at 11:09 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t46904_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t46904_1 && git checkout t46904_1

Patchset v1 (message #1) is on t46904_1

Jump to latest
#1Japin Li
japinli@hotmail.com

Hi, hackers

GetRunningTransactionData requires holding both ProcArrayLock and
XidGenLock (in that order). Then LogStandbySnapshot releases those
locks in that order. However, to reduce the frequency of having to
wait for XidGenLock while holding ProcArrayLock, ProcArrayAdd releases
them in reversed acquisition order.

The comments of LogStandbySnapshot says:

GetRunningTransactionData() acquired ProcArrayLock, we must release it.
For Hot Standby this can be done before inserting the WAL record
because ProcArrayApplyRecoveryInfo() rechecks the commit status using
the clog. For logical decoding, though, the lock can't be released
early because the clog might be "in the future" from the POV of the
historic snapshot. This would allow for situations where we're waiting
for the end of a transaction listed in the xl_running_xacts record
which, according to the WAL, has committed before the xl_running_xacts
record. Fortunately this routine isn't executed frequently, and it's
only a shared lock.

This comment is only for ProcArrayLock, not for XidGenLock. IIUC,
LogCurrentRunningXacts doesn't need holding XidGenLock, right?

Does there any sense to release them in reversed acquisition order in
LogStandbySnapshot like ProcArrayRemove?

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.

Attachments:

t46904_1
locks-release-order-in-LogStandbySnapshot.difftext/x-diffDownload+3-3
#2Andres Freund
andres@anarazel.de
In reply to: Japin Li (#1)
Re: Locks release order in LogStandbySnapshot

Hi,

On 2022-11-09 11:03:04 +0800, Japin Li wrote:

GetRunningTransactionData requires holding both ProcArrayLock and
XidGenLock (in that order). Then LogStandbySnapshot releases those
locks in that order. However, to reduce the frequency of having to
wait for XidGenLock while holding ProcArrayLock, ProcArrayAdd releases
them in reversed acquisition order.

The comments of LogStandbySnapshot says:

GetRunningTransactionData() acquired ProcArrayLock, we must release it.
For Hot Standby this can be done before inserting the WAL record
because ProcArrayApplyRecoveryInfo() rechecks the commit status using
the clog. For logical decoding, though, the lock can't be released
early because the clog might be "in the future" from the POV of the
historic snapshot. This would allow for situations where we're waiting
for the end of a transaction listed in the xl_running_xacts record
which, according to the WAL, has committed before the xl_running_xacts
record. Fortunately this routine isn't executed frequently, and it's
only a shared lock.

This comment is only for ProcArrayLock, not for XidGenLock. IIUC,
LogCurrentRunningXacts doesn't need holding XidGenLock, right?

I think it does. If we allow xid assignment before LogCurrentRunningXacts() is
done, those new xids would not have been mentioned in the xl_running_xacts
record, despite already running. Which I think result in corrupted snapshots
during hot standby and logical decoding.

Does there any sense to release them in reversed acquisition order in
LogStandbySnapshot like ProcArrayRemove?

I don't think it's worth optimizing for, this happens at a low frequency
(whereas connection establishment can be very frequent). And due to the above,
we can sometimes release ProcArrayLock earlier.

Greetings,

Andres Freund

#3Japin Li
japinli@hotmail.com
In reply to: Andres Freund (#2)
Re: Locks release order in LogStandbySnapshot

On Wed, 09 Nov 2022 at 11:21, Andres Freund <andres@anarazel.de> wrote:

I think it does. If we allow xid assignment before LogCurrentRunningXacts() is
done, those new xids would not have been mentioned in the xl_running_xacts
record, despite already running. Which I think result in corrupted snapshots
during hot standby and logical decoding.

Does there any sense to release them in reversed acquisition order in
LogStandbySnapshot like ProcArrayRemove?

I don't think it's worth optimizing for, this happens at a low frequency
(whereas connection establishment can be very frequent). And due to the above,
we can sometimes release ProcArrayLock earlier.

Thanks for the explanation! Got it.

--
Regrads,
Japin Li.
ChengDu WenWu Information Technology Co.,Ltd.