README.tuplock and SHARE lock

Started by Will Mortensenabout 1 year ago5 messages
#1Will Mortensen
will@extrahop.com

README.tuplock says:

There is one exception
here: since infomask space is limited, we do not provide a separate bit
for SELECT FOR SHARE, so we have to use the extended info in a MultiXact in
that case. (The other cases, SELECT FOR UPDATE and SELECT FOR KEY SHARE, are
presumably more commonly used due to being the standards-mandated locking
mechanism, or heavily used by the RI code, so we want to provide fast paths
for those.)

But looking at the explanations of the infomask bits further down (as
updated in commit cdbdc4382743fcfabb3437ea7c4d103adaa01324), as well
as the actual code for locking a not-yet-locked tuple in
compute_new_xmax_infomask(), this doesn't seem to be true. Was this an
oversight?

#2Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Will Mortensen (#1)
Re: README.tuplock and SHARE lock

On 2024-Nov-18, Will Mortensen wrote:

README.tuplock says:

There is one exception
here: since infomask space is limited, we do not provide a separate bit
for SELECT FOR SHARE, so we have to use the extended info in a MultiXact in
that case. (The other cases, SELECT FOR UPDATE and SELECT FOR KEY SHARE, are
presumably more commonly used due to being the standards-mandated locking
mechanism, or heavily used by the RI code, so we want to provide fast paths
for those.)

But looking at the explanations of the infomask bits further down (as
updated in commit cdbdc4382743fcfabb3437ea7c4d103adaa01324), as well
as the actual code for locking a not-yet-locked tuple in
compute_new_xmax_infomask(), this doesn't seem to be true. Was this an
oversight?

Hmm, yeah, it seems you're correct about this being an oversight -- we
don't necessarily use a multixact if all we want to do is to store a FOR
SHARE lock. Instead, what we do is mark the tuple with two lock bits,
per this bit in src/include/access/htup_details.h:

#define HEAP_XMAX_SHR_LOCK (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK)

This can be seen in a WAL_DEBUG build, when doing SELECT FOR SHARE of a
tuple does this:

2024-11-19 09:39:37.011 CET [65326] LOG: INSERT @ 0/1B92EB0: - Heap/LOCK: xmax: 744, off: 1, infobits: [LOCK_ONLY, EXCL_LOCK, KEYSHR_LOCK], flags: 0x00

Note that the infobits don't include anything about it being MULTI.
Contrast that with the case where the same tuple is locked by two
transactions simultaneously:

2024-11-19 09:40:45.582 CET [65326] LOG: INSERT @ 0/1B93008: - MultiXact/CREATE_ID: 1 offset 1 nmembers 2: 745 (sh) 746 (sh)
2024-11-19 09:40:45.582 CET [65326] LOG: INSERT @ 0/1B93040: - Heap/LOCK: xmax: 1, off: 1, infobits: [IS_MULTI, LOCK_ONLY, EXCL_LOCK, KEYSHR_LOCK], flags: 0x00

Here we first see the MultiXact being created (with two transactions,
both using SHARE mode), then the tuple being locked with IS_MULTI.

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
Subversion to GIT: the shortest path to happiness I've ever heard of
(Alexey Klyukin)

#3Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Alvaro Herrera (#2)
Re: README.tuplock and SHARE lock

On 2024-Nov-19, Alvaro Herrera wrote:

Hmm, yeah, it seems you're correct about this being an oversight -- we
don't necessarily use a multixact if all we want to do is to store a FOR
SHARE lock.

The "Infomask Bits" section explains correctly. I propose the following
amendment,

diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index 31c52ad28f9..843c2e58f92 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -70,13 +70,8 @@ KEY SHARE        conflict
 When there is a single locker in a tuple, we can just store the locking info
 in the tuple itself.  We do this by storing the locker's Xid in XMAX, and
-setting infomask bits specifying the locking strength.  There is one exception
-here: since infomask space is limited, we do not provide a separate bit
-for SELECT FOR SHARE, so we have to use the extended info in a MultiXact in
-that case.  (The other cases, SELECT FOR UPDATE and SELECT FOR KEY SHARE, are
-presumably more commonly used due to being the standards-mandated locking
-mechanism, or heavily used by the RI code, so we want to provide fast paths
-for those.)
+setting infomask bits specifying the locking strength.  See "Infomask Bits"
+below for details on the bit patterns we use.

MultiXacts
----------

--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
"Ellos andaban todos desnudos como su madre los parió, y también las mujeres,
aunque no vi más que una, harto moza, y todos los que yo vi eran todos
mancebos, que ninguno vi de edad de más de XXX años" (Cristóbal Colón)

#4Will Mortensen
will@extrahop.com
In reply to: Alvaro Herrera (#3)
Re: README.tuplock and SHARE lock

Sounds good to me. :-)

#5Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Will Mortensen (#4)
Re: README.tuplock and SHARE lock

On 2024-Nov-19, Will Mortensen wrote:

Sounds good to me. :-)

Pushed, thanks for reporting this.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"Entristecido, Wutra (canción de Las Barreras)
echa a Freyr a rodar
y a nosotros al mar"