1 /*-------------------------------------------------------------------------
4 * POSTGRES lock manager code
6 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/storage/lmgr/lmgr.c
13 *-------------------------------------------------------------------------
18 #include "access/subtrans.h"
19 #include "access/transam.h"
20 #include "access/xact.h"
21 #include "catalog/catalog.h"
22 #include "miscadmin.h"
23 #include "storage/lmgr.h"
24 #include "storage/procarray.h"
25 #include "utils/inval.h"
29 * RelationInitLockInfo
30 * Initializes the lock information in a relation descriptor.
32 * relcache.c must call this during creation of any reldesc.
35 RelationInitLockInfo(Relation relation)
37 Assert(RelationIsValid(relation));
38 Assert(OidIsValid(RelationGetRelid(relation)));
40 relation->rd_lockInfo.lockRelId.relId = RelationGetRelid(relation);
42 if (relation->rd_rel->relisshared)
43 relation->rd_lockInfo.lockRelId.dbId = InvalidOid;
45 relation->rd_lockInfo.lockRelId.dbId = MyDatabaseId;
49 * SetLocktagRelationOid
50 * Set up a locktag for a relation, given only relation OID
53 SetLocktagRelationOid(LOCKTAG *tag, Oid relid)
57 if (IsSharedRelation(relid))
62 SET_LOCKTAG_RELATION(*tag, dbid, relid);
68 * Lock a relation given only its OID. This should generally be used
69 * before attempting to open the relation's relcache entry.
72 LockRelationOid(Oid relid, LOCKMODE lockmode)
75 LockAcquireResult res;
77 SetLocktagRelationOid(&tag, relid);
79 res = LockAcquire(&tag, lockmode, false, false);
82 * Now that we have the lock, check for invalidation messages, so that we
83 * will update or flush any stale relcache entry before we try to use it.
84 * We can skip this in the not-uncommon case that we already had the same
85 * type of lock being requested, since then no one else could have
86 * modified the relcache entry in an undesirable way. (In the case where
87 * our own xact modifies the rel, the relcache update happens via
88 * CommandCounterIncrement, not here.)
90 if (res != LOCKACQUIRE_ALREADY_HELD)
91 AcceptInvalidationMessages();
95 * ConditionalLockRelationOid
97 * As above, but only lock if we can get the lock without blocking.
98 * Returns TRUE iff the lock was acquired.
100 * NOTE: we do not currently need conditional versions of all the
101 * LockXXX routines in this file, but they could easily be added if needed.
104 ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
107 LockAcquireResult res;
109 SetLocktagRelationOid(&tag, relid);
111 res = LockAcquire(&tag, lockmode, false, true);
113 if (res == LOCKACQUIRE_NOT_AVAIL)
117 * Now that we have the lock, check for invalidation messages; see notes
118 * in LockRelationOid.
120 if (res != LOCKACQUIRE_ALREADY_HELD)
121 AcceptInvalidationMessages();
129 * Unlock, given a LockRelId. This is preferred over UnlockRelationOid
133 UnlockRelationId(LockRelId *relid, LOCKMODE lockmode)
137 SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
139 LockRelease(&tag, lockmode, false);
145 * Unlock, given only a relation Oid. Use UnlockRelationId if you can.
148 UnlockRelationOid(Oid relid, LOCKMODE lockmode)
152 SetLocktagRelationOid(&tag, relid);
154 LockRelease(&tag, lockmode, false);
160 * This is a convenience routine for acquiring an additional lock on an
161 * already-open relation. Never try to do "relation_open(foo, NoLock)"
162 * and then lock with this.
165 LockRelation(Relation relation, LOCKMODE lockmode)
168 LockAcquireResult res;
170 SET_LOCKTAG_RELATION(tag,
171 relation->rd_lockInfo.lockRelId.dbId,
172 relation->rd_lockInfo.lockRelId.relId);
174 res = LockAcquire(&tag, lockmode, false, false);
177 * Now that we have the lock, check for invalidation messages; see notes
178 * in LockRelationOid.
180 if (res != LOCKACQUIRE_ALREADY_HELD)
181 AcceptInvalidationMessages();
185 * ConditionalLockRelation
187 * This is a convenience routine for acquiring an additional lock on an
188 * already-open relation. Never try to do "relation_open(foo, NoLock)"
189 * and then lock with this.
192 ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
195 LockAcquireResult res;
197 SET_LOCKTAG_RELATION(tag,
198 relation->rd_lockInfo.lockRelId.dbId,
199 relation->rd_lockInfo.lockRelId.relId);
201 res = LockAcquire(&tag, lockmode, false, true);
203 if (res == LOCKACQUIRE_NOT_AVAIL)
207 * Now that we have the lock, check for invalidation messages; see notes
208 * in LockRelationOid.
210 if (res != LOCKACQUIRE_ALREADY_HELD)
211 AcceptInvalidationMessages();
219 * This is a convenience routine for unlocking a relation without also
223 UnlockRelation(Relation relation, LOCKMODE lockmode)
227 SET_LOCKTAG_RELATION(tag,
228 relation->rd_lockInfo.lockRelId.dbId,
229 relation->rd_lockInfo.lockRelId.relId);
231 LockRelease(&tag, lockmode, false);
235 * LockRelationIdForSession
237 * This routine grabs a session-level lock on the target relation. The
238 * session lock persists across transaction boundaries. It will be removed
239 * when UnlockRelationIdForSession() is called, or if an ereport(ERROR) occurs,
240 * or if the backend exits.
242 * Note that one should also grab a transaction-level lock on the rel
243 * in any transaction that actually uses the rel, to ensure that the
244 * relcache entry is up to date.
247 LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
251 SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
253 (void) LockAcquire(&tag, lockmode, true, false);
257 * UnlockRelationIdForSession
260 UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
264 SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);
266 LockRelease(&tag, lockmode, true);
270 * LockRelationForExtension
272 * This lock tag is used to interlock addition of pages to relations.
273 * We need such locking because bufmgr/smgr definition of P_NEW is not
274 * race-condition-proof.
276 * We assume the caller is already holding some type of regular lock on
277 * the relation, so no AcceptInvalidationMessages call is needed here.
280 LockRelationForExtension(Relation relation, LOCKMODE lockmode)
284 SET_LOCKTAG_RELATION_EXTEND(tag,
285 relation->rd_lockInfo.lockRelId.dbId,
286 relation->rd_lockInfo.lockRelId.relId);
288 (void) LockAcquire(&tag, lockmode, false, false);
292 * UnlockRelationForExtension
295 UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
299 SET_LOCKTAG_RELATION_EXTEND(tag,
300 relation->rd_lockInfo.lockRelId.dbId,
301 relation->rd_lockInfo.lockRelId.relId);
303 LockRelease(&tag, lockmode, false);
309 * Obtain a page-level lock. This is currently used by some index access
310 * methods to lock individual index pages.
313 LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
317 SET_LOCKTAG_PAGE(tag,
318 relation->rd_lockInfo.lockRelId.dbId,
319 relation->rd_lockInfo.lockRelId.relId,
322 (void) LockAcquire(&tag, lockmode, false, false);
326 * ConditionalLockPage
328 * As above, but only lock if we can get the lock without blocking.
329 * Returns TRUE iff the lock was acquired.
332 ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
336 SET_LOCKTAG_PAGE(tag,
337 relation->rd_lockInfo.lockRelId.dbId,
338 relation->rd_lockInfo.lockRelId.relId,
341 return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
348 UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode)
352 SET_LOCKTAG_PAGE(tag,
353 relation->rd_lockInfo.lockRelId.dbId,
354 relation->rd_lockInfo.lockRelId.relId,
357 LockRelease(&tag, lockmode, false);
363 * Obtain a tuple-level lock. This is used in a less-than-intuitive fashion
364 * because we can't afford to keep a separate lock in shared memory for every
365 * tuple. See heap_lock_tuple before using this!
368 LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
372 SET_LOCKTAG_TUPLE(tag,
373 relation->rd_lockInfo.lockRelId.dbId,
374 relation->rd_lockInfo.lockRelId.relId,
375 ItemPointerGetBlockNumber(tid),
376 ItemPointerGetOffsetNumber(tid));
378 (void) LockAcquire(&tag, lockmode, false, false);
382 * ConditionalLockTuple
384 * As above, but only lock if we can get the lock without blocking.
385 * Returns TRUE iff the lock was acquired.
388 ConditionalLockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
392 SET_LOCKTAG_TUPLE(tag,
393 relation->rd_lockInfo.lockRelId.dbId,
394 relation->rd_lockInfo.lockRelId.relId,
395 ItemPointerGetBlockNumber(tid),
396 ItemPointerGetOffsetNumber(tid));
398 return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);
405 UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
409 SET_LOCKTAG_TUPLE(tag,
410 relation->rd_lockInfo.lockRelId.dbId,
411 relation->rd_lockInfo.lockRelId.relId,
412 ItemPointerGetBlockNumber(tid),
413 ItemPointerGetOffsetNumber(tid));
415 LockRelease(&tag, lockmode, false);
419 * XactLockTableInsert
421 * Insert a lock showing that the given transaction ID is running ---
422 * this is done when an XID is acquired by a transaction or subtransaction.
423 * The lock can then be used to wait for the transaction to finish.
426 XactLockTableInsert(TransactionId xid)
430 SET_LOCKTAG_TRANSACTION(tag, xid);
432 (void) LockAcquire(&tag, ExclusiveLock, false, false);
436 * XactLockTableDelete
438 * Delete the lock showing that the given transaction ID is running.
439 * (This is never used for main transaction IDs; those locks are only
440 * released implicitly at transaction end. But we do use it for subtrans IDs.)
443 XactLockTableDelete(TransactionId xid)
447 SET_LOCKTAG_TRANSACTION(tag, xid);
449 LockRelease(&tag, ExclusiveLock, false);
455 * Wait for the specified transaction to commit or abort.
457 * Note that this does the right thing for subtransactions: if we wait on a
458 * subtransaction, we will exit as soon as it aborts or its top parent commits.
459 * It takes some extra work to ensure this, because to save on shared memory
460 * the XID lock of a subtransaction is released when it ends, whether
461 * successfully or unsuccessfully. So we have to check if it's "still running"
462 * and if so wait for its parent.
465 XactLockTableWait(TransactionId xid)
471 Assert(TransactionIdIsValid(xid));
472 Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
474 SET_LOCKTAG_TRANSACTION(tag, xid);
476 (void) LockAcquire(&tag, ShareLock, false, false);
478 LockRelease(&tag, ShareLock, false);
480 if (!TransactionIdIsInProgress(xid))
482 xid = SubTransGetParent(xid);
487 * ConditionalXactLockTableWait
489 * As above, but only lock if we can get the lock without blocking.
490 * Returns TRUE if the lock was acquired.
493 ConditionalXactLockTableWait(TransactionId xid)
499 Assert(TransactionIdIsValid(xid));
500 Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
502 SET_LOCKTAG_TRANSACTION(tag, xid);
504 if (LockAcquire(&tag, ShareLock, false, true) == LOCKACQUIRE_NOT_AVAIL)
507 LockRelease(&tag, ShareLock, false);
509 if (!TransactionIdIsInProgress(xid))
511 xid = SubTransGetParent(xid);
519 * VirtualXactLockTableInsert
521 * Insert a lock showing that the given virtual transaction ID is running ---
522 * this is done at main transaction start when its VXID is assigned.
523 * The lock can then be used to wait for the transaction to finish.
526 VirtualXactLockTableInsert(VirtualTransactionId vxid)
530 Assert(VirtualTransactionIdIsValid(vxid));
532 SET_LOCKTAG_VIRTUALTRANSACTION(tag, vxid);
534 (void) LockAcquire(&tag, ExclusiveLock, false, false);
538 * VirtualXactLockTableWait
540 * Waits until the lock on the given VXID is released, which shows that
541 * the top-level transaction owning the VXID has ended.
544 VirtualXactLockTableWait(VirtualTransactionId vxid)
548 Assert(VirtualTransactionIdIsValid(vxid));
550 SET_LOCKTAG_VIRTUALTRANSACTION(tag, vxid);
552 (void) LockAcquire(&tag, ShareLock, false, false);
554 LockRelease(&tag, ShareLock, false);
558 * ConditionalVirtualXactLockTableWait
560 * As above, but only lock if we can get the lock without blocking.
561 * Returns TRUE if the lock was acquired.
564 ConditionalVirtualXactLockTableWait(VirtualTransactionId vxid)
568 Assert(VirtualTransactionIdIsValid(vxid));
570 SET_LOCKTAG_VIRTUALTRANSACTION(tag, vxid);
572 if (LockAcquire(&tag, ShareLock, false, true) == LOCKACQUIRE_NOT_AVAIL)
575 LockRelease(&tag, ShareLock, false);
584 * Obtain a lock on a general object of the current database. Don't use
585 * this for shared objects (such as tablespaces). It's unwise to apply it
586 * to relations, also, since a lock taken this way will NOT conflict with
587 * locks taken via LockRelation and friends.
590 LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
595 SET_LOCKTAG_OBJECT(tag,
601 (void) LockAcquire(&tag, lockmode, false, false);
603 /* Make sure syscaches are up-to-date with any changes we waited for */
604 AcceptInvalidationMessages();
608 * UnlockDatabaseObject
611 UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
616 SET_LOCKTAG_OBJECT(tag,
622 LockRelease(&tag, lockmode, false);
628 * Obtain a lock on a shared-across-databases object.
631 LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
636 SET_LOCKTAG_OBJECT(tag,
642 (void) LockAcquire(&tag, lockmode, false, false);
644 /* Make sure syscaches are up-to-date with any changes we waited for */
645 AcceptInvalidationMessages();
652 UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
657 SET_LOCKTAG_OBJECT(tag,
663 LockRelease(&tag, lockmode, false);
667 * LockSharedObjectForSession
669 * Obtain a session-level lock on a shared-across-databases object.
670 * See LockRelationIdForSession for notes about session-level locks.
673 LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
678 SET_LOCKTAG_OBJECT(tag,
684 (void) LockAcquire(&tag, lockmode, true, false);
688 * UnlockSharedObjectForSession
691 UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
696 SET_LOCKTAG_OBJECT(tag,
702 LockRelease(&tag, lockmode, true);
707 * Append a description of a lockable object to buf.
709 * Ideally we would print names for the numeric values, but that requires
710 * getting locks on system tables, which might cause problems since this is
711 * typically used to report deadlock situations.
714 DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
716 switch ((LockTagType) tag->locktag_type)
718 case LOCKTAG_RELATION:
719 appendStringInfo(buf,
720 _("relation %u of database %u"),
722 tag->locktag_field1);
724 case LOCKTAG_RELATION_EXTEND:
725 appendStringInfo(buf,
726 _("extension of relation %u of database %u"),
728 tag->locktag_field1);
731 appendStringInfo(buf,
732 _("page %u of relation %u of database %u"),
735 tag->locktag_field1);
738 appendStringInfo(buf,
739 _("tuple (%u,%u) of relation %u of database %u"),
743 tag->locktag_field1);
745 case LOCKTAG_TRANSACTION:
746 appendStringInfo(buf,
748 tag->locktag_field1);
750 case LOCKTAG_VIRTUALTRANSACTION:
751 appendStringInfo(buf,
752 _("virtual transaction %d/%u"),
754 tag->locktag_field2);
757 appendStringInfo(buf,
758 _("object %u of class %u of database %u"),
761 tag->locktag_field1);
763 case LOCKTAG_USERLOCK:
764 /* reserved for old contrib code, now on pgfoundry */
765 appendStringInfo(buf,
766 _("user lock [%u,%u,%u]"),
769 tag->locktag_field3);
771 case LOCKTAG_ADVISORY:
772 appendStringInfo(buf,
773 _("advisory lock [%u,%u,%u,%u]"),
777 tag->locktag_field4);
780 appendStringInfo(buf,
781 _("unrecognized locktag type %d"),
782 (int) tag->locktag_type);