summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-04-29 22:28:24 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-04-29 22:28:24 +0000
commit3a694bb0a16fea1662f1ffd31506a72effdd4a93 (patch)
tree50bbf16b3117aada49b2709f524b3bdcf1a36815 /src/include
parent32d3b47e6f05c7137debddb68730a25fe1bb0cd6 (diff)
downloadpostgresql-3a694bb0a16fea1662f1ffd31506a72effdd4a93.tar.gz
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.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/catalog/pg_attribute.h12
-rw-r--r--src/include/catalog/pg_class.h7
-rw-r--r--src/include/storage/lmgr.h8
-rw-r--r--src/include/storage/lock.h112
4 files changed, 101 insertions, 38 deletions
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index a58f1d886b..ddca993a68 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.116 2005/04/14 01:38:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.117 2005/04/29 22:28:24 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -461,14 +461,4 @@ DATA(insert ( 1259 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
{ 0, {"indexprs"}, 25, -1, -1, 9, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 0, {"indpred"}, 25, -1, -1, 10, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
-/* ----------------
- * pg_xactlock - this is not a real relation, but is a placeholder
- * to allow a relation OID to be used for transaction
- * waits. We need a pg_xactlock entry in pg_class only to
- * ensure that that OID can never be allocated to a real
- * table; and this entry is just to link to that one.
- * ----------------
- */
-DATA(insert ( 376 xactlockfoo 26 0 4 1 0 -1 -1 t p i t f f t 0));
-
#endif /* PG_ATTRIBUTE_H */
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 9ffc79ad8c..e08d6d60d3 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.87 2005/04/14 01:38:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.88 2005/04/29 22:28:24 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -147,11 +147,6 @@ DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 18 0 0
DESCR("");
DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 0 f f r 25 0 0 0 0 0 t f f f _null_ ));
DESCR("");
-DATA(insert OID = 376 ( pg_xactlock PGNSP 0 PGUID 0 0 1664 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ ));
-DESCR("");
-
-/* Xact lock pseudo-table */
-#define XactLockTableId 376
#define RELKIND_INDEX 'i' /* secondary index */
#define RELKIND_RELATION 'r' /* ordinary cataloged heap */
diff --git a/src/include/storage/lmgr.h b/src/include/storage/lmgr.h
index 8d63294f5c..4d1027c174 100644
--- a/src/include/storage/lmgr.h
+++ b/src/include/storage/lmgr.h
@@ -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);
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 7f67a3ac3a..b1744325ff 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -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 struct LOCKTAG
+typedef enum LockTagType
{
- Oid relId;
- Oid dbId;
- union
- {
- BlockNumber blkno;
- TransactionId xid;
- } objId;
-
+ 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 */
/*
- * offnum should be part of objId union above, but doing that would
- * increase sizeof(LOCKTAG) due to padding. Currently used by
- * userlocks only.
+ * 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.
*/
- OffsetNumber offnum;
+ LOCKTAG_USERLOCK /* reserved for contrib/userlock */
+ /* ID info for a userlock is defined by user_locks.c */
+} LockTagType;
- LOCKMETHODID lockmethodid; /* needed by userlocks */
+/*
+ * 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
+{
+ 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)
/*