mirror of
https://github.com/postgres/postgres.git
synced 2026-03-25 11:56:13 -04:00
Move declarations related to locktags from lock.h to new locktag.h
This commit moves all the declarations related to locktags from lock.h to a new header called locktag.h. This header is useful so as code paths that care about locktags but not the lock hashtable can know about these without having to include lock.h and all its set of dependencies. This move includes the basic locktag structures and the set of macros to fill in the locktag fields before attempting to acquire a lock. Based on a suggestion from me, suggestion done while discussing a different feature. Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/abufUya2oK-_PJ3E@paquier.xyz
This commit is contained in:
parent
ce8d5fe0e2
commit
322bab7974
2 changed files with 191 additions and 172 deletions
|
|
@ -21,6 +21,7 @@
|
|||
#include "access/transam.h"
|
||||
#include "lib/ilist.h"
|
||||
#include "storage/lockdefs.h"
|
||||
#include "storage/locktag.h"
|
||||
#include "storage/lwlock.h"
|
||||
#include "storage/procnumber.h"
|
||||
#include "storage/shmem.h"
|
||||
|
|
@ -117,178 +118,6 @@ typedef struct LockMethodData
|
|||
|
||||
typedef const LockMethodData *LockMethod;
|
||||
|
||||
/*
|
||||
* Lock methods are identified by LOCKMETHODID. (Despite the declaration as
|
||||
* uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.)
|
||||
*/
|
||||
typedef uint16 LOCKMETHODID;
|
||||
|
||||
/* These identify the known lock methods */
|
||||
#define DEFAULT_LOCKMETHOD 1
|
||||
#define USER_LOCKMETHOD 2
|
||||
|
||||
/*
|
||||
* LOCKTAG is the key information needed to look up a LOCK item in the
|
||||
* lock hashtable. A LOCKTAG value uniquely identifies a lockable object.
|
||||
*
|
||||
* The LockTagType enum defines the different kinds of objects we can lock.
|
||||
* We can handle up to 256 different LockTagTypes.
|
||||
*/
|
||||
typedef enum LockTagType
|
||||
{
|
||||
LOCKTAG_RELATION, /* whole relation */
|
||||
LOCKTAG_RELATION_EXTEND, /* the right to extend a relation */
|
||||
LOCKTAG_DATABASE_FROZEN_IDS, /* pg_database.datfrozenxid */
|
||||
LOCKTAG_PAGE, /* one page of a relation */
|
||||
LOCKTAG_TUPLE, /* one physical tuple */
|
||||
LOCKTAG_TRANSACTION, /* transaction (for waiting for xact done) */
|
||||
LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */
|
||||
LOCKTAG_SPECULATIVE_TOKEN, /* speculative insertion Xid and token */
|
||||
LOCKTAG_OBJECT, /* non-relation database object */
|
||||
LOCKTAG_USERLOCK, /* reserved for old contrib/userlock code */
|
||||
LOCKTAG_ADVISORY, /* advisory user locks */
|
||||
LOCKTAG_APPLY_TRANSACTION, /* transaction being applied on a logical
|
||||
* replication subscriber */
|
||||
} LockTagType;
|
||||
|
||||
#define LOCKTAG_LAST_TYPE LOCKTAG_APPLY_TRANSACTION
|
||||
|
||||
extern PGDLLIMPORT const char *const LockTagTypeNames[];
|
||||
|
||||
/*
|
||||
* The LOCKTAG struct is defined with malice aforethought to fit into 16
|
||||
* bytes with no padding. Note that this would need adjustment if we were
|
||||
* to widen Oid, BlockNumber, or TransactionId to more than 32 bits.
|
||||
*
|
||||
* We include lockmethodid in the locktag so that a single hash table in
|
||||
* shared memory can store locks of different lockmethods.
|
||||
*/
|
||||
typedef struct LOCKTAG
|
||||
{
|
||||
uint32 locktag_field1; /* a 32-bit ID field */
|
||||
uint32 locktag_field2; /* a 32-bit ID field */
|
||||
uint32 locktag_field3; /* a 32-bit ID field */
|
||||
uint16 locktag_field4; /* a 16-bit ID field */
|
||||
uint8 locktag_type; /* see enum LockTagType */
|
||||
uint8 locktag_lockmethodid; /* lockmethod indicator */
|
||||
} LOCKTAG;
|
||||
|
||||
/*
|
||||
* These macros define how we map logical IDs of lockable objects into
|
||||
* the physical fields of LOCKTAG. Use these to set up LOCKTAG values,
|
||||
* rather than accessing the fields directly. Note multiple eval of target!
|
||||
*/
|
||||
|
||||
/* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */
|
||||
#define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (reloid), \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_RELATION, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* same ID info as RELATION */
|
||||
#define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (reloid), \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for frozen IDs is DB OID */
|
||||
#define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = 0, \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for a page is RELATION info + BlockNumber */
|
||||
#define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (reloid), \
|
||||
(locktag).locktag_field3 = (blocknum), \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_PAGE, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for a tuple is PAGE info + OffsetNumber */
|
||||
#define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (reloid), \
|
||||
(locktag).locktag_field3 = (blocknum), \
|
||||
(locktag).locktag_field4 = (offnum), \
|
||||
(locktag).locktag_type = LOCKTAG_TUPLE, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for a transaction is its TransactionId */
|
||||
#define SET_LOCKTAG_TRANSACTION(locktag,xid) \
|
||||
((locktag).locktag_field1 = (xid), \
|
||||
(locktag).locktag_field2 = 0, \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_TRANSACTION, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for a virtual transaction is its VirtualTransactionId */
|
||||
#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
|
||||
((locktag).locktag_field1 = (vxid).procNumber, \
|
||||
(locktag).locktag_field2 = (vxid).localTransactionId, \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/*
|
||||
* ID info for a speculative insert is TRANSACTION info +
|
||||
* its speculative insert counter.
|
||||
*/
|
||||
#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \
|
||||
((locktag).locktag_field1 = (xid), \
|
||||
(locktag).locktag_field2 = (token), \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/*
|
||||
* ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID
|
||||
*
|
||||
* Note: object ID has same representation as in pg_depend and
|
||||
* pg_description, but notice that we are constraining SUBID to 16 bits.
|
||||
* Also, we use DB OID = 0 for shared objects such as tablespaces.
|
||||
*/
|
||||
#define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (classoid), \
|
||||
(locktag).locktag_field3 = (objoid), \
|
||||
(locktag).locktag_field4 = (objsubid), \
|
||||
(locktag).locktag_type = LOCKTAG_OBJECT, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
#define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \
|
||||
((locktag).locktag_field1 = (id1), \
|
||||
(locktag).locktag_field2 = (id2), \
|
||||
(locktag).locktag_field3 = (id3), \
|
||||
(locktag).locktag_field4 = (id4), \
|
||||
(locktag).locktag_type = LOCKTAG_ADVISORY, \
|
||||
(locktag).locktag_lockmethodid = USER_LOCKMETHOD)
|
||||
|
||||
/*
|
||||
* ID info for a remote transaction on a logical replication subscriber is: DB
|
||||
* OID + SUBSCRIPTION OID + TRANSACTION ID + OBJID
|
||||
*/
|
||||
#define SET_LOCKTAG_APPLY_TRANSACTION(locktag,dboid,suboid,xid,objid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (suboid), \
|
||||
(locktag).locktag_field3 = (xid), \
|
||||
(locktag).locktag_field4 = (objid), \
|
||||
(locktag).locktag_type = LOCKTAG_APPLY_TRANSACTION, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/*
|
||||
* Per-locked-object lock information:
|
||||
*
|
||||
|
|
|
|||
190
src/include/storage/locktag.h
Normal file
190
src/include/storage/locktag.h
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* locktag.h
|
||||
* LOCKTAG declarations, for lookups in the Postgres lock hashtable.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/storage/locktag.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _PG_LOCKTAG_H_
|
||||
#define _PG_LOCKTAG_H_
|
||||
|
||||
/*
|
||||
* Lock methods are identified by LOCKMETHODID. (Despite the declaration as
|
||||
* uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.)
|
||||
*/
|
||||
typedef uint16 LOCKMETHODID;
|
||||
|
||||
/* These identify the known lock methods */
|
||||
#define DEFAULT_LOCKMETHOD 1
|
||||
#define USER_LOCKMETHOD 2
|
||||
|
||||
/*
|
||||
* LOCKTAG is the key information needed to look up a LOCK item in the
|
||||
* lock hashtable. A LOCKTAG value uniquely identifies a lockable object.
|
||||
*
|
||||
* The LockTagType enum defines the different kinds of objects we can lock.
|
||||
* We can handle up to 256 different LockTagTypes.
|
||||
*/
|
||||
typedef enum LockTagType
|
||||
{
|
||||
LOCKTAG_RELATION, /* whole relation */
|
||||
LOCKTAG_RELATION_EXTEND, /* the right to extend a relation */
|
||||
LOCKTAG_DATABASE_FROZEN_IDS, /* pg_database.datfrozenxid */
|
||||
LOCKTAG_PAGE, /* one page of a relation */
|
||||
LOCKTAG_TUPLE, /* one physical tuple */
|
||||
LOCKTAG_TRANSACTION, /* transaction (for waiting for xact done) */
|
||||
LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */
|
||||
LOCKTAG_SPECULATIVE_TOKEN, /* speculative insertion Xid and token */
|
||||
LOCKTAG_OBJECT, /* non-relation database object */
|
||||
LOCKTAG_USERLOCK, /* reserved for old contrib/userlock code */
|
||||
LOCKTAG_ADVISORY, /* advisory user locks */
|
||||
LOCKTAG_APPLY_TRANSACTION, /* transaction being applied on a logical
|
||||
* replication subscriber */
|
||||
} LockTagType;
|
||||
|
||||
#define LOCKTAG_LAST_TYPE LOCKTAG_APPLY_TRANSACTION
|
||||
|
||||
extern PGDLLIMPORT const char *const LockTagTypeNames[];
|
||||
|
||||
/*
|
||||
* The LOCKTAG struct is defined with malice aforethought to fit into 16
|
||||
* bytes with no padding. Note that this would need adjustment if we were
|
||||
* to widen Oid, BlockNumber, or TransactionId to more than 32 bits.
|
||||
*
|
||||
* We include lockmethodid in the locktag so that a single hash table in
|
||||
* shared memory can store locks of different lockmethods.
|
||||
*/
|
||||
typedef struct LOCKTAG
|
||||
{
|
||||
uint32 locktag_field1; /* a 32-bit ID field */
|
||||
uint32 locktag_field2; /* a 32-bit ID field */
|
||||
uint32 locktag_field3; /* a 32-bit ID field */
|
||||
uint16 locktag_field4; /* a 16-bit ID field */
|
||||
uint8 locktag_type; /* see enum LockTagType */
|
||||
uint8 locktag_lockmethodid; /* lockmethod indicator */
|
||||
} LOCKTAG;
|
||||
|
||||
/*
|
||||
* These macros define how we map logical IDs of lockable objects into
|
||||
* the physical fields of LOCKTAG. Use these to set up LOCKTAG values,
|
||||
* rather than accessing the fields directly. Note multiple eval of target!
|
||||
*/
|
||||
|
||||
/* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */
|
||||
#define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (reloid), \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_RELATION, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* same ID info as RELATION */
|
||||
#define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (reloid), \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for frozen IDs is DB OID */
|
||||
#define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = 0, \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for a page is RELATION info + BlockNumber */
|
||||
#define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (reloid), \
|
||||
(locktag).locktag_field3 = (blocknum), \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_PAGE, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for a tuple is PAGE info + OffsetNumber */
|
||||
#define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (reloid), \
|
||||
(locktag).locktag_field3 = (blocknum), \
|
||||
(locktag).locktag_field4 = (offnum), \
|
||||
(locktag).locktag_type = LOCKTAG_TUPLE, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for a transaction is its TransactionId */
|
||||
#define SET_LOCKTAG_TRANSACTION(locktag,xid) \
|
||||
((locktag).locktag_field1 = (xid), \
|
||||
(locktag).locktag_field2 = 0, \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_TRANSACTION, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/* ID info for a virtual transaction is its VirtualTransactionId */
|
||||
#define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
|
||||
((locktag).locktag_field1 = (vxid).procNumber, \
|
||||
(locktag).locktag_field2 = (vxid).localTransactionId, \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/*
|
||||
* ID info for a speculative insert is TRANSACTION info +
|
||||
* its speculative insert counter.
|
||||
*/
|
||||
#define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \
|
||||
((locktag).locktag_field1 = (xid), \
|
||||
(locktag).locktag_field2 = (token), \
|
||||
(locktag).locktag_field3 = 0, \
|
||||
(locktag).locktag_field4 = 0, \
|
||||
(locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
/*
|
||||
* ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID
|
||||
*
|
||||
* Note: object ID has same representation as in pg_depend and
|
||||
* pg_description, but notice that we are constraining SUBID to 16 bits.
|
||||
* Also, we use DB OID = 0 for shared objects such as tablespaces.
|
||||
*/
|
||||
#define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (classoid), \
|
||||
(locktag).locktag_field3 = (objoid), \
|
||||
(locktag).locktag_field4 = (objsubid), \
|
||||
(locktag).locktag_type = LOCKTAG_OBJECT, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
#define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \
|
||||
((locktag).locktag_field1 = (id1), \
|
||||
(locktag).locktag_field2 = (id2), \
|
||||
(locktag).locktag_field3 = (id3), \
|
||||
(locktag).locktag_field4 = (id4), \
|
||||
(locktag).locktag_type = LOCKTAG_ADVISORY, \
|
||||
(locktag).locktag_lockmethodid = USER_LOCKMETHOD)
|
||||
|
||||
/*
|
||||
* ID info for a remote transaction on a logical replication subscriber is: DB
|
||||
* OID + SUBSCRIPTION OID + TRANSACTION ID + OBJID
|
||||
*/
|
||||
#define SET_LOCKTAG_APPLY_TRANSACTION(locktag,dboid,suboid,xid,objid) \
|
||||
((locktag).locktag_field1 = (dboid), \
|
||||
(locktag).locktag_field2 = (suboid), \
|
||||
(locktag).locktag_field3 = (xid), \
|
||||
(locktag).locktag_field4 = (objid), \
|
||||
(locktag).locktag_type = LOCKTAG_APPLY_TRANSACTION, \
|
||||
(locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
|
||||
|
||||
#endif /* _PG_LOCKTAG_H_ */
|
||||
Loading…
Reference in a new issue