Thread: README.tuplock and SHARE lock

README.tuplock and SHARE lock

From
Will Mortensen
Date:
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?



Re: README.tuplock and SHARE lock

From
Alvaro Herrera
Date:
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)



Re: README.tuplock and SHARE lock

From
Alvaro Herrera
Date:
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)



Re: README.tuplock and SHARE lock

From
Will Mortensen
Date:
Sounds good to me. :-)