]> granicus.if.org Git - postgresql/blob - src/include/storage/lock.h
pgindent run for 8.2.
[postgresql] / src / include / storage / lock.h
1 /*-------------------------------------------------------------------------
2  *
3  * lock.h
4  *        POSTGRES low-level lock mechanism
5  *
6  *
7  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.101 2006/10/04 00:30:10 momjian Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef LOCK_H_
15 #define LOCK_H_
16
17 #include "nodes/pg_list.h"
18 #include "storage/itemptr.h"
19 #include "storage/lwlock.h"
20 #include "storage/shmem.h"
21
22
23 /* struct PGPROC is declared in proc.h, but must forward-reference it */
24 typedef struct PGPROC PGPROC;
25
26 typedef struct PROC_QUEUE
27 {
28         SHM_QUEUE       links;                  /* head of list of PGPROC objects */
29         int                     size;                   /* number of entries in list */
30 } PROC_QUEUE;
31
32 /* GUC variables */
33 extern int      max_locks_per_xact;
34
35 #ifdef LOCK_DEBUG
36 extern int      Trace_lock_oidmin;
37 extern bool Trace_locks;
38 extern bool Trace_userlocks;
39 extern int      Trace_lock_table;
40 extern bool Debug_deadlocks;
41 #endif   /* LOCK_DEBUG */
42
43
44 /*
45  * LOCKMODE is an integer (1..N) indicating a lock type.  LOCKMASK is a bit
46  * mask indicating a set of held or requested lock types (the bit 1<<mode
47  * corresponds to a particular lock mode).
48  */
49 typedef int LOCKMASK;
50 typedef int LOCKMODE;
51
52 /* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
53 #define MAX_LOCKMODES           10
54
55 #define LOCKBIT_ON(lockmode) (1 << (lockmode))
56 #define LOCKBIT_OFF(lockmode) (~(1 << (lockmode)))
57
58
59 /*
60  * This data structure defines the locking semantics associated with a
61  * "lock method".  The semantics specify the meaning of each lock mode
62  * (by defining which lock modes it conflicts with), and also whether locks
63  * of this method are transactional (ie, are released at transaction end).
64  * All of this data is constant and is kept in const tables.
65  *
66  * numLockModes -- number of lock modes (READ,WRITE,etc) that
67  *              are defined in this lock method.  Must be less than MAX_LOCKMODES.
68  *
69  * transactional -- TRUE if locks are released automatically at xact end.
70  *
71  * conflictTab -- this is an array of bitmasks showing lock
72  *              mode conflicts.  conflictTab[i] is a mask with the j-th bit
73  *              turned on if lock modes i and j conflict.  Lock modes are
74  *              numbered 1..numLockModes; conflictTab[0] is unused.
75  *
76  * lockModeNames -- ID strings for debug printouts.
77  *
78  * trace_flag -- pointer to GUC trace flag for this lock method.
79  */
80 typedef struct LockMethodData
81 {
82         int                     numLockModes;
83         bool            transactional;
84         const LOCKMASK *conflictTab;
85         const char *const * lockModeNames;
86         const bool *trace_flag;
87 } LockMethodData;
88
89 typedef const LockMethodData *LockMethod;
90
91 /*
92  * Lock methods are identified by LOCKMETHODID.  (Despite the declaration as
93  * uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.)
94  */
95 typedef uint16 LOCKMETHODID;
96
97 /* These identify the known lock methods */
98 #define DEFAULT_LOCKMETHOD      1
99 #define USER_LOCKMETHOD         2
100
101 /*
102  * These are the valid values of type LOCKMODE for all the standard lock
103  * methods (both DEFAULT and USER).
104  */
105
106 /* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
107 #define NoLock                                  0
108
109 #define AccessShareLock                 1               /* SELECT */
110 #define RowShareLock                    2               /* SELECT FOR UPDATE/FOR SHARE */
111 #define RowExclusiveLock                3               /* INSERT, UPDATE, DELETE */
112 #define ShareUpdateExclusiveLock 4              /* VACUUM (non-FULL) */
113 #define ShareLock                               5               /* CREATE INDEX */
114 #define ShareRowExclusiveLock   6               /* like EXCLUSIVE MODE, but allows ROW
115                                                                                  * SHARE */
116 #define ExclusiveLock                   7               /* blocks ROW SHARE/SELECT...FOR
117                                                                                  * UPDATE */
118 #define AccessExclusiveLock             8               /* ALTER TABLE, DROP TABLE, VACUUM
119                                                                                  * FULL, and unqualified LOCK TABLE */
120
121
122 /*
123  * LOCKTAG is the key information needed to look up a LOCK item in the
124  * lock hashtable.      A LOCKTAG value uniquely identifies a lockable object.
125  *
126  * The LockTagType enum defines the different kinds of objects we can lock.
127  * We can handle up to 256 different LockTagTypes.
128  */
129 typedef enum LockTagType
130 {
131         LOCKTAG_RELATION,                       /* whole relation */
132         /* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */
133         LOCKTAG_RELATION_EXTEND,        /* the right to extend a relation */
134         /* same ID info as RELATION */
135         LOCKTAG_PAGE,                           /* one page of a relation */
136         /* ID info for a page is RELATION info + BlockNumber */
137         LOCKTAG_TUPLE,                          /* one physical tuple */
138         /* ID info for a tuple is PAGE info + OffsetNumber */
139         LOCKTAG_TRANSACTION,            /* transaction (for waiting for xact done) */
140         /* ID info for a transaction is its TransactionId */
141         LOCKTAG_OBJECT,                         /* non-relation database object */
142         /* ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID */
143
144         /*
145          * Note: object ID has same representation as in pg_depend and
146          * pg_description, but notice that we are constraining SUBID to 16 bits.
147          * Also, we use DB OID = 0 for shared objects such as tablespaces.
148          */
149         LOCKTAG_USERLOCK,                       /* reserved for old contrib/userlock code */
150         LOCKTAG_ADVISORY                        /* advisory user locks */
151 } LockTagType;
152
153 /*
154  * The LOCKTAG struct is defined with malice aforethought to fit into 16
155  * bytes with no padding.  Note that this would need adjustment if we were
156  * to widen Oid, BlockNumber, or TransactionId to more than 32 bits.
157  *
158  * We include lockmethodid in the locktag so that a single hash table in
159  * shared memory can store locks of different lockmethods.
160  */
161 typedef struct LOCKTAG
162 {
163         uint32          locktag_field1; /* a 32-bit ID field */
164         uint32          locktag_field2; /* a 32-bit ID field */
165         uint32          locktag_field3; /* a 32-bit ID field */
166         uint16          locktag_field4; /* a 16-bit ID field */
167         uint8           locktag_type;   /* see enum LockTagType */
168         uint8           locktag_lockmethodid;   /* lockmethod indicator */
169 } LOCKTAG;
170
171 /*
172  * These macros define how we map logical IDs of lockable objects into
173  * the physical fields of LOCKTAG.      Use these to set up LOCKTAG values,
174  * rather than accessing the fields directly.  Note multiple eval of target!
175  */
176 #define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
177         ((locktag).locktag_field1 = (dboid), \
178          (locktag).locktag_field2 = (reloid), \
179          (locktag).locktag_field3 = 0, \
180          (locktag).locktag_field4 = 0, \
181          (locktag).locktag_type = LOCKTAG_RELATION, \
182          (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
183
184 #define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
185         ((locktag).locktag_field1 = (dboid), \
186          (locktag).locktag_field2 = (reloid), \
187          (locktag).locktag_field3 = 0, \
188          (locktag).locktag_field4 = 0, \
189          (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
190          (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
191
192 #define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
193         ((locktag).locktag_field1 = (dboid), \
194          (locktag).locktag_field2 = (reloid), \
195          (locktag).locktag_field3 = (blocknum), \
196          (locktag).locktag_field4 = 0, \
197          (locktag).locktag_type = LOCKTAG_PAGE, \
198          (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
199
200 #define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
201         ((locktag).locktag_field1 = (dboid), \
202          (locktag).locktag_field2 = (reloid), \
203          (locktag).locktag_field3 = (blocknum), \
204          (locktag).locktag_field4 = (offnum), \
205          (locktag).locktag_type = LOCKTAG_TUPLE, \
206          (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
207
208 #define SET_LOCKTAG_TRANSACTION(locktag,xid) \
209         ((locktag).locktag_field1 = (xid), \
210          (locktag).locktag_field2 = 0, \
211          (locktag).locktag_field3 = 0, \
212          (locktag).locktag_field4 = 0, \
213          (locktag).locktag_type = LOCKTAG_TRANSACTION, \
214          (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
215
216 #define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \
217         ((locktag).locktag_field1 = (dboid), \
218          (locktag).locktag_field2 = (classoid), \
219          (locktag).locktag_field3 = (objoid), \
220          (locktag).locktag_field4 = (objsubid), \
221          (locktag).locktag_type = LOCKTAG_OBJECT, \
222          (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
223
224 #define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \
225         ((locktag).locktag_field1 = (id1), \
226          (locktag).locktag_field2 = (id2), \
227          (locktag).locktag_field3 = (id3), \
228          (locktag).locktag_field4 = (id4), \
229          (locktag).locktag_type = LOCKTAG_ADVISORY, \
230          (locktag).locktag_lockmethodid = USER_LOCKMETHOD)
231
232
233 /*
234  * Per-locked-object lock information:
235  *
236  * tag -- uniquely identifies the object being locked
237  * grantMask -- bitmask for all lock types currently granted on this object.
238  * waitMask -- bitmask for all lock types currently awaited on this object.
239  * procLocks -- list of PROCLOCK objects for this lock.
240  * waitProcs -- queue of processes waiting for this lock.
241  * requested -- count of each lock type currently requested on the lock
242  *              (includes requests already granted!!).
243  * nRequested -- total requested locks of all types.
244  * granted -- count of each lock type currently granted on the lock.
245  * nGranted -- total granted locks of all types.
246  *
247  * Note: these counts count 1 for each backend.  Internally to a backend,
248  * there may be multiple grabs on a particular lock, but this is not reflected
249  * into shared memory.
250  */
251 typedef struct LOCK
252 {
253         /* hash key */
254         LOCKTAG         tag;                    /* unique identifier of lockable object */
255
256         /* data */
257         LOCKMASK        grantMask;              /* bitmask for lock types already granted */
258         LOCKMASK        waitMask;               /* bitmask for lock types awaited */
259         SHM_QUEUE       procLocks;              /* list of PROCLOCK objects assoc. with lock */
260         PROC_QUEUE      waitProcs;              /* list of PGPROC objects waiting on lock */
261         int                     requested[MAX_LOCKMODES];               /* counts of requested locks */
262         int                     nRequested;             /* total of requested[] array */
263         int                     granted[MAX_LOCKMODES]; /* counts of granted locks */
264         int                     nGranted;               /* total of granted[] array */
265 } LOCK;
266
267 #define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)
268
269
270 /*
271  * We may have several different backends holding or awaiting locks
272  * on the same lockable object.  We need to store some per-holder/waiter
273  * information for each such holder (or would-be holder).  This is kept in
274  * a PROCLOCK struct.
275  *
276  * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the
277  * proclock hashtable.  A PROCLOCKTAG value uniquely identifies the combination
278  * of a lockable object and a holder/waiter for that object.  (We can use
279  * pointers here because the PROCLOCKTAG need only be unique for the lifespan
280  * of the PROCLOCK, and it will never outlive the lock or the proc.)
281  *
282  * Internally to a backend, it is possible for the same lock to be held
283  * for different purposes: the backend tracks transaction locks separately
284  * from session locks.  However, this is not reflected in the shared-memory
285  * state: we only track which backend(s) hold the lock.  This is OK since a
286  * backend can never block itself.
287  *
288  * The holdMask field shows the already-granted locks represented by this
289  * proclock.  Note that there will be a proclock object, possibly with
290  * zero holdMask, for any lock that the process is currently waiting on.
291  * Otherwise, proclock objects whose holdMasks are zero are recycled
292  * as soon as convenient.
293  *
294  * releaseMask is workspace for LockReleaseAll(): it shows the locks due
295  * to be released during the current call.      This must only be examined or
296  * set by the backend owning the PROCLOCK.
297  *
298  * Each PROCLOCK object is linked into lists for both the associated LOCK
299  * object and the owning PGPROC object.  Note that the PROCLOCK is entered
300  * into these lists as soon as it is created, even if no lock has yet been
301  * granted.  A PGPROC that is waiting for a lock to be granted will also be
302  * linked into the lock's waitProcs queue.
303  */
304 typedef struct PROCLOCKTAG
305 {
306         /* NB: we assume this struct contains no padding! */
307         LOCK       *myLock;                     /* link to per-lockable-object information */
308         PGPROC     *myProc;                     /* link to PGPROC of owning backend */
309 } PROCLOCKTAG;
310
311 typedef struct PROCLOCK
312 {
313         /* tag */
314         PROCLOCKTAG tag;                        /* unique identifier of proclock object */
315
316         /* data */
317         LOCKMASK        holdMask;               /* bitmask for lock types currently held */
318         LOCKMASK        releaseMask;    /* bitmask for lock types to be released */
319         SHM_QUEUE       lockLink;               /* list link in LOCK's list of proclocks */
320         SHM_QUEUE       procLink;               /* list link in PGPROC's list of proclocks */
321 } PROCLOCK;
322
323 #define PROCLOCK_LOCKMETHOD(proclock) \
324         LOCK_LOCKMETHOD(*((proclock).tag.myLock))
325
326 /*
327  * Each backend also maintains a local hash table with information about each
328  * lock it is currently interested in.  In particular the local table counts
329  * the number of times that lock has been acquired.  This allows multiple
330  * requests for the same lock to be executed without additional accesses to
331  * shared memory.  We also track the number of lock acquisitions per
332  * ResourceOwner, so that we can release just those locks belonging to a
333  * particular ResourceOwner.
334  */
335 typedef struct LOCALLOCKTAG
336 {
337         LOCKTAG         lock;                   /* identifies the lockable object */
338         LOCKMODE        mode;                   /* lock mode for this table entry */
339 } LOCALLOCKTAG;
340
341 typedef struct LOCALLOCKOWNER
342 {
343         /*
344          * Note: if owner is NULL then the lock is held on behalf of the session;
345          * otherwise it is held on behalf of my current transaction.
346          *
347          * Must use a forward struct reference to avoid circularity.
348          */
349         struct ResourceOwnerData *owner;
350         int                     nLocks;                 /* # of times held by this owner */
351 } LOCALLOCKOWNER;
352
353 typedef struct LOCALLOCK
354 {
355         /* tag */
356         LOCALLOCKTAG tag;                       /* unique identifier of locallock entry */
357
358         /* data */
359         LOCK       *lock;                       /* associated LOCK object in shared mem */
360         PROCLOCK   *proclock;           /* associated PROCLOCK object in shmem */
361         uint32          hashcode;               /* copy of LOCKTAG's hash value */
362         int                     nLocks;                 /* total number of times lock is held */
363         int                     numLockOwners;  /* # of relevant ResourceOwners */
364         int                     maxLockOwners;  /* allocated size of array */
365         LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */
366 } LOCALLOCK;
367
368 #define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)
369
370
371 /*
372  * This struct holds information passed from lmgr internals to the lock
373  * listing user-level functions (in lockfuncs.c).       For each PROCLOCK in
374  * the system, copies of the PROCLOCK object and associated PGPROC and
375  * LOCK objects are stored.  Note there will often be multiple copies
376  * of the same PGPROC or LOCK --- to detect whether two are the same,
377  * compare the PROCLOCK tag fields.
378  */
379 typedef struct LockData
380 {
381         int                     nelements;              /* The length of each of the arrays */
382         PROCLOCK   *proclocks;
383         PGPROC     *procs;
384         LOCK       *locks;
385 } LockData;
386
387
388 /* Result codes for LockAcquire() */
389 typedef enum
390 {
391         LOCKACQUIRE_NOT_AVAIL,          /* lock not available, and dontWait=true */
392         LOCKACQUIRE_OK,                         /* lock successfully acquired */
393         LOCKACQUIRE_ALREADY_HELD        /* incremented count for lock already held */
394 } LockAcquireResult;
395
396
397 /*
398  * The lockmgr's shared hash tables are partitioned to reduce contention.
399  * To determine which partition a given locktag belongs to, compute the tag's
400  * hash code with LockTagHashCode(), then apply one of these macros.
401  * NB: NUM_LOCK_PARTITIONS must be a power of 2!
402  */
403 #define LockHashPartition(hashcode) \
404         ((hashcode) % NUM_LOCK_PARTITIONS)
405 #define LockHashPartitionLock(hashcode) \
406         ((LWLockId) (FirstLockMgrLock + LockHashPartition(hashcode)))
407
408
409 /*
410  * function prototypes
411  */
412 extern void InitLocks(void);
413 extern LockMethod GetLocksMethodTable(const LOCK *lock);
414 extern uint32 LockTagHashCode(const LOCKTAG *locktag);
415 extern LockAcquireResult LockAcquire(const LOCKTAG *locktag,
416                         LOCKMODE lockmode,
417                         bool sessionLock,
418                         bool dontWait);
419 extern bool LockRelease(const LOCKTAG *locktag,
420                         LOCKMODE lockmode, bool sessionLock);
421 extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks);
422 extern void LockReleaseCurrentOwner(void);
423 extern void LockReassignCurrentOwner(void);
424 extern List *GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode);
425 extern void AtPrepare_Locks(void);
426 extern void PostPrepare_Locks(TransactionId xid);
427 extern int LockCheckConflicts(LockMethod lockMethodTable,
428                                    LOCKMODE lockmode,
429                                    LOCK *lock, PROCLOCK *proclock, PGPROC *proc);
430 extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode);
431 extern void GrantAwaitedLock(void);
432 extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
433 extern Size LockShmemSize(void);
434 extern LockData *GetLockStatusData(void);
435 extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);
436
437 extern void lock_twophase_recover(TransactionId xid, uint16 info,
438                                           void *recdata, uint32 len);
439 extern void lock_twophase_postcommit(TransactionId xid, uint16 info,
440                                                  void *recdata, uint32 len);
441 extern void lock_twophase_postabort(TransactionId xid, uint16 info,
442                                                 void *recdata, uint32 len);
443
444 extern bool DeadLockCheck(PGPROC *proc);
445 extern void DeadLockReport(void);
446 extern void RememberSimpleDeadLock(PGPROC *proc1,
447                                            LOCKMODE lockmode,
448                                            LOCK *lock,
449                                            PGPROC *proc2);
450 extern void InitDeadLockChecking(void);
451
452 #ifdef LOCK_DEBUG
453 extern void DumpLocks(PGPROC *proc);
454 extern void DumpAllLocks(void);
455 #endif
456
457 #endif   /* LOCK_H */