📄 lmgr.c
字号:
relation->rd_lockInfo.lockRelId.dbId, relation->rd_lockInfo.lockRelId.relId, ItemPointerGetBlockNumber(tid), ItemPointerGetOffsetNumber(tid)); (void) LockAcquire(&tag, lockmode, false, false);}/* * ConditionalLockTuple * * As above, but only lock if we can get the lock without blocking. * Returns TRUE iff the lock was acquired. */boolConditionalLockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode){ LOCKTAG tag; SET_LOCKTAG_TUPLE(tag, relation->rd_lockInfo.lockRelId.dbId, relation->rd_lockInfo.lockRelId.relId, ItemPointerGetBlockNumber(tid), ItemPointerGetOffsetNumber(tid)); return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);}/* * UnlockTuple */voidUnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode){ LOCKTAG tag; SET_LOCKTAG_TUPLE(tag, relation->rd_lockInfo.lockRelId.dbId, relation->rd_lockInfo.lockRelId.relId, ItemPointerGetBlockNumber(tid), ItemPointerGetOffsetNumber(tid)); LockRelease(&tag, lockmode, false);}/* * XactLockTableInsert * * Insert a lock showing that the given transaction ID is running --- * this is done when an XID is acquired by a transaction or subtransaction. * The lock can then be used to wait for the transaction to finish. */voidXactLockTableInsert(TransactionId xid){ LOCKTAG tag; SET_LOCKTAG_TRANSACTION(tag, xid); (void) LockAcquire(&tag, ExclusiveLock, false, false);}/* * XactLockTableDelete * * Delete the lock showing that the given transaction ID is running. * (This is never used for main transaction IDs; those locks are only * released implicitly at transaction end. But we do use it for subtrans IDs.) */voidXactLockTableDelete(TransactionId xid){ LOCKTAG tag; SET_LOCKTAG_TRANSACTION(tag, xid); LockRelease(&tag, ExclusiveLock, false);}/* * XactLockTableWait * * Wait for the specified transaction to commit or abort. * * Note that this does the right thing for subtransactions: if we wait on a * subtransaction, we will exit as soon as it aborts or its top parent commits. * It takes some extra work to ensure this, because to save on shared memory * the XID lock of a subtransaction is released when it ends, whether * successfully or unsuccessfully. So we have to check if it's "still running" * and if so wait for its parent. */voidXactLockTableWait(TransactionId xid){ LOCKTAG tag; for (;;) { Assert(TransactionIdIsValid(xid)); Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny())); SET_LOCKTAG_TRANSACTION(tag, xid); (void) LockAcquire(&tag, ShareLock, false, false); LockRelease(&tag, ShareLock, false); if (!TransactionIdIsInProgress(xid)) break; xid = SubTransGetParent(xid); }}/* * ConditionalXactLockTableWait * * As above, but only lock if we can get the lock without blocking. * Returns TRUE if the lock was acquired. */boolConditionalXactLockTableWait(TransactionId xid){ LOCKTAG tag; for (;;) { Assert(TransactionIdIsValid(xid)); Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny())); SET_LOCKTAG_TRANSACTION(tag, xid); if (LockAcquire(&tag, ShareLock, false, true) == LOCKACQUIRE_NOT_AVAIL) return false; LockRelease(&tag, ShareLock, false); if (!TransactionIdIsInProgress(xid)) break; xid = SubTransGetParent(xid); } return true;}/* * VirtualXactLockTableInsert * * Insert a lock showing that the given virtual transaction ID is running --- * this is done at main transaction start when its VXID is assigned. * The lock can then be used to wait for the transaction to finish. */voidVirtualXactLockTableInsert(VirtualTransactionId vxid){ LOCKTAG tag; Assert(VirtualTransactionIdIsValid(vxid)); SET_LOCKTAG_VIRTUALTRANSACTION(tag, vxid); (void) LockAcquire(&tag, ExclusiveLock, false, false);}/* * VirtualXactLockTableWait * * Waits until the lock on the given VXID is released, which shows that * the top-level transaction owning the VXID has ended. */voidVirtualXactLockTableWait(VirtualTransactionId vxid){ LOCKTAG tag; Assert(VirtualTransactionIdIsValid(vxid)); SET_LOCKTAG_VIRTUALTRANSACTION(tag, vxid); (void) LockAcquire(&tag, ShareLock, false, false); LockRelease(&tag, ShareLock, false);}/* * ConditionalVirtualXactLockTableWait * * As above, but only lock if we can get the lock without blocking. * Returns TRUE if the lock was acquired. */boolConditionalVirtualXactLockTableWait(VirtualTransactionId vxid){ LOCKTAG tag; Assert(VirtualTransactionIdIsValid(vxid)); SET_LOCKTAG_VIRTUALTRANSACTION(tag, vxid); if (LockAcquire(&tag, ShareLock, false, true) == LOCKACQUIRE_NOT_AVAIL) return false; LockRelease(&tag, ShareLock, false); return true;}/* * LockDatabaseObject * * Obtain a lock on a general object of the current database. Don't use * this for shared objects (such as tablespaces). It's unwise to apply it * to relations, also, since a lock taken this way will NOT conflict with * locks taken via LockRelation and friends. */voidLockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode){ LOCKTAG tag; SET_LOCKTAG_OBJECT(tag, MyDatabaseId, classid, objid, objsubid); (void) LockAcquire(&tag, lockmode, false, false);}/* * UnlockDatabaseObject */voidUnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode){ LOCKTAG tag; SET_LOCKTAG_OBJECT(tag, MyDatabaseId, classid, objid, objsubid); LockRelease(&tag, lockmode, false);}/* * LockSharedObject * * Obtain a lock on a shared-across-databases object. */voidLockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode){ LOCKTAG tag; SET_LOCKTAG_OBJECT(tag, InvalidOid, classid, objid, objsubid); (void) LockAcquire(&tag, lockmode, false, false); /* Make sure syscaches are up-to-date with any changes we waited for */ AcceptInvalidationMessages();}/* * UnlockSharedObject */voidUnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode){ LOCKTAG tag; SET_LOCKTAG_OBJECT(tag, InvalidOid, classid, objid, objsubid); LockRelease(&tag, lockmode, false);}/* * Append a description of a lockable object to buf. * * Ideally we would print names for the numeric values, but that requires * getting locks on system tables, which might cause problems since this is * typically used to report deadlock situations. */voidDescribeLockTag(StringInfo buf, const LOCKTAG *tag){ switch ((LockTagType) tag->locktag_type) { case LOCKTAG_RELATION: appendStringInfo(buf, _("relation %u of database %u"), tag->locktag_field2, tag->locktag_field1); break; case LOCKTAG_RELATION_EXTEND: appendStringInfo(buf, _("extension of relation %u of database %u"), tag->locktag_field2, tag->locktag_field1); break; case LOCKTAG_PAGE: appendStringInfo(buf, _("page %u of relation %u of database %u"), tag->locktag_field3, tag->locktag_field2, tag->locktag_field1); break; case LOCKTAG_TUPLE: appendStringInfo(buf, _("tuple (%u,%u) of relation %u of database %u"), tag->locktag_field3, tag->locktag_field4, tag->locktag_field2, tag->locktag_field1); break; case LOCKTAG_TRANSACTION: appendStringInfo(buf, _("transaction %u"), tag->locktag_field1); break; case LOCKTAG_VIRTUALTRANSACTION: appendStringInfo(buf, _("virtual transaction %d/%u"), tag->locktag_field1, tag->locktag_field2); break; case LOCKTAG_OBJECT: appendStringInfo(buf, _("object %u of class %u of database %u"), tag->locktag_field3, tag->locktag_field2, tag->locktag_field1); break; case LOCKTAG_USERLOCK: /* reserved for old contrib code, now on pgfoundry */ appendStringInfo(buf, _("user lock [%u,%u,%u]"), tag->locktag_field1, tag->locktag_field2, tag->locktag_field3); break; case LOCKTAG_ADVISORY: appendStringInfo(buf, _("advisory lock [%u,%u,%u,%u]"), tag->locktag_field1, tag->locktag_field2, tag->locktag_field3, tag->locktag_field4); break; default: appendStringInfo(buf, _("unrecognized locktag type %d"), (int) tag->locktag_type); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -