mirror of
https://github.com/postgres/postgres.git
synced 2025-10-28 11:55:03 +03:00
Restructure LOCKTAG as per discussions of a couple months ago.
Essentially, we shoehorn in a lockable-object-type field by taking a byte away from the lockmethodid, which can surely fit in one byte instead of two. This allows less artificial definitions of all the other fields of LOCKTAG; we can get rid of the special pg_xactlock pseudo-relation, and also support locks on individual tuples and general database objects (including shared objects). None of those possibilities are actually exploited just yet, however. I removed pg_xactlock from pg_class, but did not force initdb for that change. At this point, relkind 's' (SPECIAL) is unused and could be removed entirely.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/storage/lmgr.h,v 1.46 2005/04/28 21:47:18 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/storage/lmgr.h,v 1.47 2005/04/29 22:28:24 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -51,7 +51,11 @@ extern void UnlockRelation(Relation relation, LOCKMODE lockmode);
|
||||
extern void LockRelationForSession(LockRelId *relid, LOCKMODE lockmode);
|
||||
extern void UnlockRelationForSession(LockRelId *relid, LOCKMODE lockmode);
|
||||
|
||||
/* Lock a page (mainly used for indexes) */
|
||||
/* Lock a relation for extension */
|
||||
extern void LockRelationForExtension(Relation relation, LOCKMODE lockmode);
|
||||
extern void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode);
|
||||
|
||||
/* Lock a page (currently only used within indexes) */
|
||||
extern void LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode);
|
||||
extern bool ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode);
|
||||
extern void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.84 2004/12/31 22:03:42 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.85 2005/04/29 22:28:24 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -58,7 +58,8 @@ typedef int LOCKMODE;
|
||||
/*
|
||||
* There is normally only one lock method, the default one.
|
||||
* If user locks are enabled, an additional lock method is present.
|
||||
* Lock methods are identified by LOCKMETHODID.
|
||||
* 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;
|
||||
|
||||
@@ -103,27 +104,100 @@ typedef LockMethodData *LockMethod;
|
||||
/*
|
||||
* 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 */
|
||||
/* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */
|
||||
LOCKTAG_RELATION_EXTEND, /* the right to extend a relation */
|
||||
/* same ID info as RELATION */
|
||||
LOCKTAG_PAGE, /* one page of a relation */
|
||||
/* ID info for a page is RELATION info + BlockNumber */
|
||||
LOCKTAG_TUPLE, /* one physical tuple */
|
||||
/* ID info for a tuple is PAGE info + OffsetNumber */
|
||||
LOCKTAG_TRANSACTION, /* transaction (for waiting for xact done) */
|
||||
/* ID info for a transaction is its TransactionId */
|
||||
LOCKTAG_OBJECT, /* non-relation database object */
|
||||
/* 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.
|
||||
*/
|
||||
LOCKTAG_USERLOCK /* reserved for contrib/userlock */
|
||||
/* ID info for a userlock is defined by user_locks.c */
|
||||
} LockTagType;
|
||||
|
||||
/*
|
||||
* 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. For largely
|
||||
* historical reasons, it's passed to the lock.c routines as a separate
|
||||
* argument and then stored into the locktag.
|
||||
*/
|
||||
typedef struct LOCKTAG
|
||||
{
|
||||
Oid relId;
|
||||
Oid dbId;
|
||||
union
|
||||
{
|
||||
BlockNumber blkno;
|
||||
TransactionId xid;
|
||||
} objId;
|
||||
|
||||
/*
|
||||
* offnum should be part of objId union above, but doing that would
|
||||
* increase sizeof(LOCKTAG) due to padding. Currently used by
|
||||
* userlocks only.
|
||||
*/
|
||||
OffsetNumber offnum;
|
||||
|
||||
LOCKMETHODID lockmethodid; /* needed by userlocks */
|
||||
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!
|
||||
*/
|
||||
#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)
|
||||
|
||||
#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)
|
||||
|
||||
#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)
|
||||
|
||||
#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)
|
||||
|
||||
#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)
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
/*
|
||||
* Per-locked-object lock information:
|
||||
@@ -157,7 +231,7 @@ typedef struct LOCK
|
||||
int nGranted; /* total of granted[] array */
|
||||
} LOCK;
|
||||
|
||||
#define LOCK_LOCKMETHOD(lock) ((lock).tag.lockmethodid)
|
||||
#define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)
|
||||
|
||||
|
||||
/*
|
||||
@@ -211,7 +285,7 @@ typedef struct PROCLOCK
|
||||
} PROCLOCK;
|
||||
|
||||
#define PROCLOCK_LOCKMETHOD(proclock) \
|
||||
(((LOCK *) MAKE_PTR((proclock).tag.lock))->tag.lockmethodid)
|
||||
LOCK_LOCKMETHOD(*((LOCK *) MAKE_PTR((proclock).tag.lock)))
|
||||
|
||||
/*
|
||||
* Each backend also maintains a local hash table with information about each
|
||||
@@ -253,7 +327,7 @@ typedef struct LOCALLOCK
|
||||
LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */
|
||||
} LOCALLOCK;
|
||||
|
||||
#define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.lockmethodid)
|
||||
#define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user