⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lmgr.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * lmgr.c *	  POSTGRES lock manager code * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.96.2.1 2008/03/04 19:54:13 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/subtrans.h"#include "access/transam.h"#include "access/xact.h"#include "catalog/catalog.h"#include "miscadmin.h"#include "storage/lmgr.h"#include "storage/procarray.h"#include "utils/inval.h"/* * RelationInitLockInfo *		Initializes the lock information in a relation descriptor. * *		relcache.c must call this during creation of any reldesc. */voidRelationInitLockInfo(Relation relation){	Assert(RelationIsValid(relation));	Assert(OidIsValid(RelationGetRelid(relation)));	relation->rd_lockInfo.lockRelId.relId = RelationGetRelid(relation);	if (relation->rd_rel->relisshared)		relation->rd_lockInfo.lockRelId.dbId = InvalidOid;	else		relation->rd_lockInfo.lockRelId.dbId = MyDatabaseId;}/* * SetLocktagRelationOid *		Set up a locktag for a relation, given only relation OID */static inline voidSetLocktagRelationOid(LOCKTAG *tag, Oid relid){	Oid			dbid;	if (IsSharedRelation(relid))		dbid = InvalidOid;	else		dbid = MyDatabaseId;	SET_LOCKTAG_RELATION(*tag, dbid, relid);}/* *		LockRelationOid * * Lock a relation given only its OID.	This should generally be used * before attempting to open the relation's relcache entry. */voidLockRelationOid(Oid relid, LOCKMODE lockmode){	LOCKTAG		tag;	LockAcquireResult res;	SetLocktagRelationOid(&tag, relid);	res = LockAcquire(&tag, lockmode, false, false);	/*	 * Now that we have the lock, check for invalidation messages, so that we	 * will update or flush any stale relcache entry before we try to use it.	 * We can skip this in the not-uncommon case that we already had the same	 * type of lock being requested, since then no one else could have	 * modified the relcache entry in an undesirable way.  (In the case where	 * our own xact modifies the rel, the relcache update happens via	 * CommandCounterIncrement, not here.)	 */	if (res != LOCKACQUIRE_ALREADY_HELD)		AcceptInvalidationMessages();}/* *		ConditionalLockRelationOid * * As above, but only lock if we can get the lock without blocking. * Returns TRUE iff the lock was acquired. * * NOTE: we do not currently need conditional versions of all the * LockXXX routines in this file, but they could easily be added if needed. */boolConditionalLockRelationOid(Oid relid, LOCKMODE lockmode){	LOCKTAG		tag;	LockAcquireResult res;	SetLocktagRelationOid(&tag, relid);	res = LockAcquire(&tag, lockmode, false, true);	if (res == LOCKACQUIRE_NOT_AVAIL)		return false;	/*	 * Now that we have the lock, check for invalidation messages; see notes	 * in LockRelationOid.	 */	if (res != LOCKACQUIRE_ALREADY_HELD)		AcceptInvalidationMessages();	return true;}/* *		UnlockRelationId * * Unlock, given a LockRelId.  This is preferred over UnlockRelationOid * for speed reasons. */voidUnlockRelationId(LockRelId *relid, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);	LockRelease(&tag, lockmode, false);}/* *		UnlockRelationOid * * Unlock, given only a relation Oid.  Use UnlockRelationId if you can. */voidUnlockRelationOid(Oid relid, LOCKMODE lockmode){	LOCKTAG		tag;	SetLocktagRelationOid(&tag, relid);	LockRelease(&tag, lockmode, false);}/* *		LockRelation * * This is a convenience routine for acquiring an additional lock on an * already-open relation.  Never try to do "relation_open(foo, NoLock)" * and then lock with this. */voidLockRelation(Relation relation, LOCKMODE lockmode){	LOCKTAG		tag;	LockAcquireResult res;	SET_LOCKTAG_RELATION(tag,						 relation->rd_lockInfo.lockRelId.dbId,						 relation->rd_lockInfo.lockRelId.relId);	res = LockAcquire(&tag, lockmode, false, false);	/*	 * Now that we have the lock, check for invalidation messages; see notes	 * in LockRelationOid.	 */	if (res != LOCKACQUIRE_ALREADY_HELD)		AcceptInvalidationMessages();}/* *		ConditionalLockRelation * * This is a convenience routine for acquiring an additional lock on an * already-open relation.  Never try to do "relation_open(foo, NoLock)" * and then lock with this. */boolConditionalLockRelation(Relation relation, LOCKMODE lockmode){	LOCKTAG		tag;	LockAcquireResult res;	SET_LOCKTAG_RELATION(tag,						 relation->rd_lockInfo.lockRelId.dbId,						 relation->rd_lockInfo.lockRelId.relId);	res = LockAcquire(&tag, lockmode, false, true);	if (res == LOCKACQUIRE_NOT_AVAIL)		return false;	/*	 * Now that we have the lock, check for invalidation messages; see notes	 * in LockRelationOid.	 */	if (res != LOCKACQUIRE_ALREADY_HELD)		AcceptInvalidationMessages();	return true;}/* *		UnlockRelation * * This is a convenience routine for unlocking a relation without also * closing it. */voidUnlockRelation(Relation relation, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_RELATION(tag,						 relation->rd_lockInfo.lockRelId.dbId,						 relation->rd_lockInfo.lockRelId.relId);	LockRelease(&tag, lockmode, false);}/* *		LockRelationIdForSession * * This routine grabs a session-level lock on the target relation.	The * session lock persists across transaction boundaries.  It will be removed * when UnlockRelationIdForSession() is called, or if an ereport(ERROR) occurs, * or if the backend exits. * * Note that one should also grab a transaction-level lock on the rel * in any transaction that actually uses the rel, to ensure that the * relcache entry is up to date. */voidLockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);	(void) LockAcquire(&tag, lockmode, true, false);}/* *		UnlockRelationIdForSession */voidUnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_RELATION(tag, relid->dbId, relid->relId);	LockRelease(&tag, lockmode, true);}/* *		LockRelationForExtension * * This lock tag is used to interlock addition of pages to relations. * We need such locking because bufmgr/smgr definition of P_NEW is not * race-condition-proof. * * We assume the caller is already holding some type of regular lock on * the relation, so no AcceptInvalidationMessages call is needed here. */voidLockRelationForExtension(Relation relation, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_RELATION_EXTEND(tag,								relation->rd_lockInfo.lockRelId.dbId,								relation->rd_lockInfo.lockRelId.relId);	(void) LockAcquire(&tag, lockmode, false, false);}/* *		UnlockRelationForExtension */voidUnlockRelationForExtension(Relation relation, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_RELATION_EXTEND(tag,								relation->rd_lockInfo.lockRelId.dbId,								relation->rd_lockInfo.lockRelId.relId);	LockRelease(&tag, lockmode, false);}/* *		LockPage * * Obtain a page-level lock.  This is currently used by some index access * methods to lock individual index pages. */voidLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_PAGE(tag,					 relation->rd_lockInfo.lockRelId.dbId,					 relation->rd_lockInfo.lockRelId.relId,					 blkno);	(void) LockAcquire(&tag, lockmode, false, false);}/* *		ConditionalLockPage * * As above, but only lock if we can get the lock without blocking. * Returns TRUE iff the lock was acquired. */boolConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_PAGE(tag,					 relation->rd_lockInfo.lockRelId.dbId,					 relation->rd_lockInfo.lockRelId.relId,					 blkno);	return (LockAcquire(&tag, lockmode, false, true) != LOCKACQUIRE_NOT_AVAIL);}/* *		UnlockPage */voidUnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_PAGE(tag,					 relation->rd_lockInfo.lockRelId.dbId,					 relation->rd_lockInfo.lockRelId.relId,					 blkno);	LockRelease(&tag, lockmode, false);}/* *		LockTuple * * Obtain a tuple-level lock.  This is used in a less-than-intuitive fashion * because we can't afford to keep a separate lock in shared memory for every * tuple.  See heap_lock_tuple before using this! */voidLockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode){	LOCKTAG		tag;	SET_LOCKTAG_TUPLE(tag,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -