mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Lmgr cleanup, new locking modes for LLL.
This commit is contained in:
parent
83d3626b1f
commit
0d78e8c112
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.39 1998/07/13 16:34:49 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.40 1998/08/01 15:26:12 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -114,18 +114,18 @@ RelationGetBufferWithBuffer(Relation relation,
|
|||||||
Buffer buffer)
|
Buffer buffer)
|
||||||
{
|
{
|
||||||
BufferDesc *bufHdr;
|
BufferDesc *bufHdr;
|
||||||
LockRelId lrelId;
|
|
||||||
|
|
||||||
if (BufferIsValid(buffer))
|
if (BufferIsValid(buffer))
|
||||||
{
|
{
|
||||||
if (!BufferIsLocal(buffer))
|
if (!BufferIsLocal(buffer))
|
||||||
{
|
{
|
||||||
|
LockRelId *lrelId = &(((LockInfo)(relation->lockInfo))->lockRelId);
|
||||||
|
|
||||||
bufHdr = &BufferDescriptors[buffer - 1];
|
bufHdr = &BufferDescriptors[buffer - 1];
|
||||||
lrelId = RelationGetLockRelId(relation);
|
|
||||||
SpinAcquire(BufMgrLock);
|
SpinAcquire(BufMgrLock);
|
||||||
if (bufHdr->tag.blockNum == blockNumber &&
|
if (bufHdr->tag.blockNum == blockNumber &&
|
||||||
bufHdr->tag.relId.relId == lrelId.relId &&
|
bufHdr->tag.relId.relId == lrelId->relId &&
|
||||||
bufHdr->tag.relId.dbId == lrelId.dbId)
|
bufHdr->tag.relId.dbId == lrelId->dbId)
|
||||||
{
|
{
|
||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
return (buffer);
|
return (buffer);
|
||||||
@ -1282,7 +1282,7 @@ BufferGetRelation(Buffer buffer)
|
|||||||
Assert(!BufferIsLocal(buffer)); /* not supported for local buffers */
|
Assert(!BufferIsLocal(buffer)); /* not supported for local buffers */
|
||||||
|
|
||||||
/* XXX should be a critical section */
|
/* XXX should be a critical section */
|
||||||
relid = LockRelIdGetRelationId(BufferDescriptors[buffer - 1].tag.relId);
|
relid = BufferDescriptors[buffer - 1].tag.relId.relId;
|
||||||
relation = RelationIdGetRelation(relid);
|
relation = RelationIdGetRelation(relid);
|
||||||
|
|
||||||
RelationDecrementReferenceCount(relation);
|
RelationDecrementReferenceCount(relation);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.15 1998/07/26 04:30:41 scrappy Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.16 1998/08/01 15:26:24 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -51,220 +51,48 @@
|
|||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
#include "access/transam.h" /* for AmiTransactionId */
|
#include "access/transam.h" /* for AmiTransactionId */
|
||||||
|
|
||||||
static void LockRelIdAssign(LockRelId *lockRelId, Oid dbId, Oid relId);
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
*
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
#define MaxRetries 4 /* XXX about 1/4 minute--a hack */
|
|
||||||
|
|
||||||
#define IntentReadRelationLock 0x0100
|
|
||||||
#define ReadRelationLock 0x0200
|
|
||||||
#define IntentWriteRelationLock 0x0400
|
|
||||||
#define WriteRelationLock 0x0800
|
|
||||||
#define IntentReadPageLock 0x1000
|
|
||||||
#define ReadTupleLock 0x2000
|
|
||||||
|
|
||||||
#define TupleLevelLockCountMask 0x000f
|
|
||||||
|
|
||||||
#define TupleLevelLockLimit 10
|
|
||||||
|
|
||||||
extern Oid MyDatabaseId;
|
extern Oid MyDatabaseId;
|
||||||
|
|
||||||
LockRelId VariableRelationLockRelId = {
|
|
||||||
RelOid_pg_variable,
|
|
||||||
InvalidOid
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LockRelIdGetDatabaseId --
|
|
||||||
* Returns database identifier for a "lock" relation identifier.
|
|
||||||
*/
|
|
||||||
/* ----------------
|
|
||||||
* LockRelIdGetDatabaseId
|
|
||||||
*
|
|
||||||
* Note: The argument may not be correct, if it is not used soon
|
|
||||||
* after it is created.
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
#ifdef NOT_USED
|
|
||||||
Oid
|
|
||||||
LockRelIdGetDatabaseId(LockRelId lockRelId)
|
|
||||||
{
|
|
||||||
return (lockRelId.dbId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LockRelIdGetRelationId --
|
|
||||||
* Returns relation identifier for a "lock" relation identifier.
|
|
||||||
*/
|
|
||||||
Oid
|
|
||||||
LockRelIdGetRelationId(LockRelId lockRelId)
|
|
||||||
{
|
|
||||||
return (lockRelId.relId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DatabaseIdIsMyDatabaseId --
|
|
||||||
* True iff database object identifier is valid in my present database.
|
|
||||||
*/
|
|
||||||
#ifdef NOT_USED
|
|
||||||
bool
|
|
||||||
DatabaseIdIsMyDatabaseId(Oid databaseId)
|
|
||||||
{
|
|
||||||
return (bool)
|
|
||||||
(!OidIsValid(databaseId) || databaseId == MyDatabaseId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LockRelIdContainsMyDatabaseId --
|
|
||||||
* True iff "lock" relation identifier is valid in my present database.
|
|
||||||
*/
|
|
||||||
#ifdef NOT_USED
|
|
||||||
bool
|
|
||||||
LockRelIdContainsMyDatabaseId(LockRelId lockRelId)
|
|
||||||
{
|
|
||||||
return (bool)
|
|
||||||
(!OidIsValid(lockRelId.dbId) || lockRelId.dbId == MyDatabaseId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RelationInitLockInfo --
|
* RelationInitLockInfo --
|
||||||
* Initializes the lock information in a relation descriptor.
|
* Initializes the lock information in a relation descriptor.
|
||||||
*/
|
*/
|
||||||
/* ----------------
|
|
||||||
* RelationInitLockInfo
|
|
||||||
*
|
|
||||||
* XXX processingVariable is a hack to prevent problems during
|
|
||||||
* VARIABLE relation initialization.
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
RelationInitLockInfo(Relation relation)
|
RelationInitLockInfo(Relation relation)
|
||||||
{
|
{
|
||||||
LockInfo info;
|
LockInfo info;
|
||||||
char *relname;
|
char *relname;
|
||||||
Oid relationid;
|
MemoryContext oldcxt;
|
||||||
bool processingVariable;
|
extern Oid MyDatabaseId; /* XXX use include */
|
||||||
extern Oid MyDatabaseId; /* XXX use include */
|
extern GlobalMemory CacheCxt;
|
||||||
extern GlobalMemory CacheCxt;
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* sanity checks
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
Assert(RelationIsValid(relation));
|
Assert(RelationIsValid(relation));
|
||||||
Assert(OidIsValid(RelationGetRelationId(relation)));
|
Assert(OidIsValid(RelationGetRelationId(relation)));
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* get information from relation descriptor
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
info = (LockInfo) relation->lockInfo;
|
info = (LockInfo) relation->lockInfo;
|
||||||
relname = (char *) RelationGetRelationName(relation);
|
|
||||||
relationid = RelationGetRelationId(relation);
|
if (LockInfoIsValid(info))
|
||||||
processingVariable = (strcmp(relname, VariableRelationName) == 0);
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* create a new lockinfo if not already done
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
if (!PointerIsValid(info))
|
|
||||||
{
|
|
||||||
MemoryContext oldcxt;
|
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
|
|
||||||
info = (LockInfo) palloc(sizeof(LockInfoData));
|
|
||||||
MemoryContextSwitchTo(oldcxt);
|
|
||||||
}
|
|
||||||
else if (processingVariable)
|
|
||||||
{
|
|
||||||
if (IsTransactionState())
|
|
||||||
{
|
|
||||||
TransactionIdStore(GetCurrentTransactionId(),
|
|
||||||
&info->transactionIdData);
|
|
||||||
}
|
|
||||||
info->flags = 0x0;
|
|
||||||
return; /* prevent an infinite loop--still true? */
|
|
||||||
}
|
|
||||||
else if (info->initialized)
|
|
||||||
{
|
|
||||||
/* ------------
|
|
||||||
* If we've already initialized we're done.
|
|
||||||
* ------------
|
|
||||||
*/
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
relname = (char *) RelationGetRelationName(relation);
|
||||||
|
|
||||||
/* ----------------
|
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
|
||||||
* initialize lockinfo.dbId and .relId appropriately
|
info = (LockInfo) palloc(sizeof(LockInfoData));
|
||||||
* ----------------
|
MemoryContextSwitchTo(oldcxt);
|
||||||
*/
|
|
||||||
|
info->lockRelId.relId = RelationGetRelationId(relation);
|
||||||
if (IsSharedSystemRelationName(relname))
|
if (IsSharedSystemRelationName(relname))
|
||||||
LockRelIdAssign(&info->lockRelId, InvalidOid, relationid);
|
info->lockRelId.dbId = InvalidOid;
|
||||||
else
|
else
|
||||||
LockRelIdAssign(&info->lockRelId, MyDatabaseId, relationid);
|
info->lockRelId.dbId = MyDatabaseId;
|
||||||
|
|
||||||
/* ----------------
|
#ifdef LowLevelLocking
|
||||||
* store the transaction id in the lockInfo field
|
memset(info->lockHeld, 0, sizeof(info->lockHeld));
|
||||||
* ----------------
|
#endif
|
||||||
*/
|
|
||||||
if (processingVariable)
|
|
||||||
TransactionIdStore(AmiTransactionId,
|
|
||||||
&info->transactionIdData);
|
|
||||||
else if (IsTransactionState())
|
|
||||||
TransactionIdStore(GetCurrentTransactionId(),
|
|
||||||
&info->transactionIdData);
|
|
||||||
else
|
|
||||||
StoreInvalidTransactionId(&(info->transactionIdData));
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* initialize rest of lockinfo
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
info->flags = 0x0;
|
|
||||||
info->initialized = (bool) true;
|
|
||||||
relation->lockInfo = (Pointer) info;
|
relation->lockInfo = (Pointer) info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* RelationDiscardLockInfo
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
#ifdef LOCKDEBUG
|
|
||||||
#define LOCKDEBUG_20 \
|
|
||||||
elog(DEBUG, "DiscardLockInfo: NULL relation->lockInfo")
|
|
||||||
#else
|
|
||||||
#define LOCKDEBUG_20
|
|
||||||
#endif /* LOCKDEBUG */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RelationDiscardLockInfo --
|
|
||||||
* Discards the lock information in a relation descriptor.
|
|
||||||
*/
|
|
||||||
#ifdef NOT_USED
|
|
||||||
void
|
|
||||||
RelationDiscardLockInfo(Relation relation)
|
|
||||||
{
|
|
||||||
if (!LockInfoIsValid(relation->lockInfo))
|
|
||||||
{
|
|
||||||
LOCKDEBUG_20;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pfree(relation->lockInfo);
|
|
||||||
relation->lockInfo = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RelationSetLockForDescriptorOpen --
|
* RelationSetLockForDescriptorOpen --
|
||||||
* Sets read locks for a relation descriptor.
|
* Sets read locks for a relation descriptor.
|
||||||
@ -337,7 +165,6 @@ RelationSetLockForRead(Relation relation)
|
|||||||
{
|
{
|
||||||
RelationInitLockInfo(relation);
|
RelationInitLockInfo(relation);
|
||||||
lockinfo = (LockInfo) relation->lockInfo;
|
lockinfo = (LockInfo) relation->lockInfo;
|
||||||
lockinfo->flags |= ReadRelationLock;
|
|
||||||
MultiLockReln(lockinfo, READ_LOCK);
|
MultiLockReln(lockinfo, READ_LOCK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -433,7 +260,6 @@ RelationSetLockForWrite(Relation relation)
|
|||||||
{
|
{
|
||||||
RelationInitLockInfo(relation);
|
RelationInitLockInfo(relation);
|
||||||
lockinfo = (LockInfo) relation->lockInfo;
|
lockinfo = (LockInfo) relation->lockInfo;
|
||||||
lockinfo->flags |= WriteRelationLock;
|
|
||||||
MultiLockReln(lockinfo, WRITE_LOCK);
|
MultiLockReln(lockinfo, WRITE_LOCK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -484,120 +310,6 @@ RelationUnsetLockForWrite(Relation relation)
|
|||||||
MultiReleaseReln(lockinfo, WRITE_LOCK);
|
MultiReleaseReln(lockinfo, WRITE_LOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* RelationSetLockForTupleRead
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
#ifdef LOCKDEBUG
|
|
||||||
#define LOCKDEBUG_80 \
|
|
||||||
elog(DEBUG, "RelationSetLockForTupleRead(%s[%d,%d], 0x%x) called", \
|
|
||||||
RelationGetRelationName(relation), lockRelId.dbId, lockRelId.relId, \
|
|
||||||
itemPointer)
|
|
||||||
#define LOCKDEBUG_81 \
|
|
||||||
elog(DEBUG, "RelationSetLockForTupleRead() escalating")
|
|
||||||
#else
|
|
||||||
#define LOCKDEBUG_80
|
|
||||||
#define LOCKDEBUG_81
|
|
||||||
#endif /* LOCKDEBUG */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RelationSetLockForTupleRead --
|
|
||||||
* Sets tuple level read lock.
|
|
||||||
*/
|
|
||||||
#ifdef NOT_USED
|
|
||||||
void
|
|
||||||
RelationSetLockForTupleRead(Relation relation, ItemPointer itemPointer)
|
|
||||||
{
|
|
||||||
LockInfo lockinfo;
|
|
||||||
TransactionId curXact;
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* sanity checks
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
Assert(RelationIsValid(relation));
|
|
||||||
if (LockingDisabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
LOCKDEBUG_80;
|
|
||||||
|
|
||||||
/* ---------------------
|
|
||||||
* If our lock info is invalid don't bother trying to short circuit
|
|
||||||
* the lock manager.
|
|
||||||
* ---------------------
|
|
||||||
*/
|
|
||||||
if (!LockInfoIsValid(relation->lockInfo))
|
|
||||||
{
|
|
||||||
RelationInitLockInfo(relation);
|
|
||||||
lockinfo = (LockInfo) relation->lockInfo;
|
|
||||||
lockinfo->flags |=
|
|
||||||
IntentReadRelationLock |
|
|
||||||
IntentReadPageLock |
|
|
||||||
ReadTupleLock;
|
|
||||||
MultiLockTuple(lockinfo, itemPointer, READ_LOCK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lockinfo = (LockInfo) relation->lockInfo;
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* no need to set a lower granularity lock
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
curXact = GetCurrentTransactionId();
|
|
||||||
if ((lockinfo->flags & ReadRelationLock) &&
|
|
||||||
TransactionIdEquals(curXact, lockinfo->transactionIdData))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* If we don't already have a tuple lock this transaction
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
if (!((lockinfo->flags & ReadTupleLock) &&
|
|
||||||
TransactionIdEquals(curXact, lockinfo->transactionIdData)))
|
|
||||||
{
|
|
||||||
|
|
||||||
lockinfo->flags |=
|
|
||||||
IntentReadRelationLock |
|
|
||||||
IntentReadPageLock |
|
|
||||||
ReadTupleLock;
|
|
||||||
|
|
||||||
/* clear count */
|
|
||||||
lockinfo->flags &= ~TupleLevelLockCountMask;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (TupleLevelLockLimit == (TupleLevelLockCountMask &
|
|
||||||
lockinfo->flags))
|
|
||||||
{
|
|
||||||
LOCKDEBUG_81;
|
|
||||||
|
|
||||||
/* escalate */
|
|
||||||
MultiLockReln(lockinfo, READ_LOCK);
|
|
||||||
|
|
||||||
/* clear count */
|
|
||||||
lockinfo->flags &= ~TupleLevelLockCountMask;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* increment count */
|
|
||||||
lockinfo->flags =
|
|
||||||
(lockinfo->flags & ~TupleLevelLockCountMask) |
|
|
||||||
(1 + (TupleLevelLockCountMask & lockinfo->flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionIdStore(curXact, &lockinfo->transactionIdData);
|
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* Lock the tuple.
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
MultiLockTuple(lockinfo, itemPointer, READ_LOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* RelationSetLockForReadPage
|
* RelationSetLockForReadPage
|
||||||
* ----------------
|
* ----------------
|
||||||
@ -902,12 +614,3 @@ RelationUnsetLockForExtend(Relation relation)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Create an LockRelid --- Why not just pass in a pointer to the storage?
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
LockRelIdAssign(LockRelId *lockRelId, Oid dbId, Oid relId)
|
|
||||||
{
|
|
||||||
lockRelId->dbId = dbId;
|
|
||||||
lockRelId->relId = relId;
|
|
||||||
}
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/multi.c,v 1.20 1998/07/13 16:34:51 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Attic/multi.c,v 1.21 1998/08/01 15:26:26 vadim Exp $
|
||||||
*
|
*
|
||||||
* NOTES:
|
* NOTES:
|
||||||
* (1) The lock.c module assumes that the caller here is doing
|
* (1) The lock.c module assumes that the caller here is doing
|
||||||
@ -36,6 +36,55 @@ static bool
|
|||||||
MultiRelease(LOCKMETHOD lockmethod, LOCKTAG *tag, LOCKMODE lockmode,
|
MultiRelease(LOCKMETHOD lockmethod, LOCKTAG *tag, LOCKMODE lockmode,
|
||||||
PG_LOCK_LEVEL level);
|
PG_LOCK_LEVEL level);
|
||||||
|
|
||||||
|
#ifdef LowLevelLocking
|
||||||
|
|
||||||
|
static MASK MultiConflicts[] = {
|
||||||
|
(int) NULL,
|
||||||
|
|
||||||
|
/* RowShareLock */
|
||||||
|
(1 << ExclusiveLock),
|
||||||
|
|
||||||
|
/* RowExclusiveLock */
|
||||||
|
(1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) | (1 << ShareLock),
|
||||||
|
|
||||||
|
/* ShareLock */
|
||||||
|
(1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) |
|
||||||
|
(1 << RowExclusiveLock),
|
||||||
|
|
||||||
|
/* ShareRowExclusiveLock */
|
||||||
|
(1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) |
|
||||||
|
(1 << ShareLock) | (1 << RowExclusiveLock),
|
||||||
|
|
||||||
|
/* ExclusiveLock */
|
||||||
|
(1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) | (1 << ShareLock) |
|
||||||
|
(1 << RowExclusiveLock) | (1 << RowShareLock),
|
||||||
|
|
||||||
|
/* ObjShareLock */
|
||||||
|
(1 << ObjExclusiveLock),
|
||||||
|
|
||||||
|
/* ObjExclusiveLock */
|
||||||
|
(1 << ObjExclusiveLock) | (1 << ObjShareLock),
|
||||||
|
|
||||||
|
/* ExtendLock */
|
||||||
|
(1 << ExtendLock)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write locks have higher priority than read locks and extend locks. May
|
||||||
|
* want to treat INTENT locks differently.
|
||||||
|
*/
|
||||||
|
static int MultiPrios[] = {
|
||||||
|
(int) NULL,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INTENT indicates to higher level that a lower level lock has been
|
* INTENT indicates to higher level that a lower level lock has been
|
||||||
* set. For example, a write lock on a tuple conflicts with a write
|
* set. For example, a write lock on a tuple conflicts with a write
|
||||||
@ -43,7 +92,7 @@ MultiRelease(LOCKMETHOD lockmethod, LOCKTAG *tag, LOCKMODE lockmode,
|
|||||||
* WRITE conflict between the tuple's intent lock and the relation's
|
* WRITE conflict between the tuple's intent lock and the relation's
|
||||||
* write lock.
|
* write lock.
|
||||||
*/
|
*/
|
||||||
static int MultiConflicts[] = {
|
static MASK MultiConflicts[] = {
|
||||||
(int) NULL,
|
(int) NULL,
|
||||||
/* All reads and writes at any level conflict with a write lock */
|
/* All reads and writes at any level conflict with a write lock */
|
||||||
(1 << WRITE_LOCK) | (1 << WRITE_INTENT) | (1 << READ_LOCK) | (1 << READ_INTENT),
|
(1 << WRITE_LOCK) | (1 << WRITE_INTENT) | (1 << READ_LOCK) | (1 << READ_INTENT),
|
||||||
@ -74,6 +123,8 @@ static int MultiPrios[] = {
|
|||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* !LowLevelLocking */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lock table identifier for this lock table. The multi-level
|
* Lock table identifier for this lock table. The multi-level
|
||||||
* lock table is ONE lock table, not three.
|
* lock table is ONE lock table, not three.
|
||||||
@ -91,7 +142,8 @@ InitMultiLevelLocks()
|
|||||||
{
|
{
|
||||||
int lockmethod;
|
int lockmethod;
|
||||||
|
|
||||||
lockmethod = LockMethodTableInit("MultiLevelLockTable", MultiConflicts, MultiPrios, 5);
|
lockmethod = LockMethodTableInit("MultiLevelLockTable",
|
||||||
|
MultiConflicts, MultiPrios, MAX_LOCKMODES - 1);
|
||||||
MultiTableId = lockmethod;
|
MultiTableId = lockmethod;
|
||||||
if (!(MultiTableId))
|
if (!(MultiTableId))
|
||||||
elog(ERROR, "InitMultiLocks: couldnt initialize lock table");
|
elog(ERROR, "InitMultiLocks: couldnt initialize lock table");
|
||||||
|
5
src/backend/utils/cache/relcache.c
vendored
5
src/backend/utils/cache/relcache.c
vendored
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.44 1998/07/27 19:38:23 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.45 1998/08/01 15:26:29 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1101,6 +1101,8 @@ formrdesc(char *relationName,
|
|||||||
*/
|
*/
|
||||||
RelationCacheInsert(relation);
|
RelationCacheInsert(relation);
|
||||||
|
|
||||||
|
RelationInitLockInfo(relation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determining this requires a scan on pg_class, but to do the scan
|
* Determining this requires a scan on pg_class, but to do the scan
|
||||||
* the rdesc for pg_class must already exist. Therefore we must do
|
* the rdesc for pg_class must already exist. Therefore we must do
|
||||||
@ -2021,6 +2023,7 @@ init_irels(void)
|
|||||||
ird->rd_support = support;
|
ird->rd_support = support;
|
||||||
|
|
||||||
RelationCacheInsert(ird);
|
RelationCacheInsert(ird);
|
||||||
|
RelationInitLockInfo(ird);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: buf_internals.h,v 1.24 1998/07/20 16:57:10 momjian Exp $
|
* $Id: buf_internals.h,v 1.25 1998/08/01 15:26:34 vadim Exp $
|
||||||
*
|
*
|
||||||
* NOTE
|
* NOTE
|
||||||
* If BUFFERPAGE0 is defined, then 0 will be used as a
|
* If BUFFERPAGE0 is defined, then 0 will be used as a
|
||||||
@ -65,24 +65,9 @@ struct buftag
|
|||||||
#define INIT_BUFFERTAG(a,xx_reln,xx_blockNum) \
|
#define INIT_BUFFERTAG(a,xx_reln,xx_blockNum) \
|
||||||
( \
|
( \
|
||||||
(a)->blockNum = xx_blockNum, \
|
(a)->blockNum = xx_blockNum, \
|
||||||
(a)->relId = RelationGetLockRelId(xx_reln) \
|
(a)->relId = ((LockInfo)(xx_reln->lockInfo))->lockRelId \
|
||||||
)
|
)
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
#define COPY_BUFFERTAG(a,b) \
|
|
||||||
( \
|
|
||||||
(a)->blockNum = (b)->blockNum, \
|
|
||||||
LockRelIdAssign(*(a),*(b)) \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define EQUAL_BUFFERTAG(a,b) \
|
|
||||||
( \
|
|
||||||
((a)->blockNum == (b)->blockNum && \
|
|
||||||
OID_Equal((a)->relId.relId,(b)->relId.relId)) \
|
|
||||||
)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BAD_BUFFER_ID(bid) ((bid<1) || (bid>(NBuffers)))
|
#define BAD_BUFFER_ID(bid) ((bid<1) || (bid>(NBuffers)))
|
||||||
#define INVALID_DESCRIPTOR (-3)
|
#define INVALID_DESCRIPTOR (-3)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: lmgr.h,v 1.13 1998/07/13 16:34:56 momjian Exp $
|
* $Id: lmgr.h,v 1.14 1998/08/01 15:26:36 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -27,45 +27,23 @@ typedef struct LockRelId
|
|||||||
Oid dbId; /* a database identifier */
|
Oid dbId; /* a database identifier */
|
||||||
} LockRelId;
|
} LockRelId;
|
||||||
|
|
||||||
|
#ifdef LowLevelLocking
|
||||||
typedef struct LockInfoData
|
typedef struct LockInfoData
|
||||||
{
|
{
|
||||||
bool initialized;
|
|
||||||
LockRelId lockRelId;
|
LockRelId lockRelId;
|
||||||
TransactionId transactionIdData;
|
bool lockHeld[MAX_LOCKMODES]; /* on table level */
|
||||||
uint16 flags;
|
|
||||||
} LockInfoData;
|
} LockInfoData;
|
||||||
|
#else
|
||||||
|
typedef struct LockInfoData
|
||||||
|
{
|
||||||
|
LockRelId lockRelId;
|
||||||
|
} LockInfoData;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef LockInfoData *LockInfo;
|
typedef LockInfoData *LockInfo;
|
||||||
|
|
||||||
#define LockInfoIsValid(lockinfo) \
|
#define LockInfoIsValid(lockinfo) PointerIsValid(lockinfo)
|
||||||
((PointerIsValid(lockinfo)) && ((LockInfo) lockinfo)->initialized)
|
|
||||||
|
|
||||||
extern LockRelId VariableRelationLockRelId;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RelationGetLockRelId --
|
|
||||||
* Returns "lock" relation identifier for a relation.
|
|
||||||
*/
|
|
||||||
/* ----------------
|
|
||||||
* final condition is a hack to prevent problems during
|
|
||||||
* VARIABLE relation initialization
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
#define RelationGetLockRelId(relation) \
|
|
||||||
( \
|
|
||||||
AssertMacro(RelationIsValid(relation)), \
|
|
||||||
(!LockInfoIsValid((LockInfo)(relation)->lockInfo)) ? \
|
|
||||||
RelationInitLockInfo(relation) \
|
|
||||||
: \
|
|
||||||
(void)NULL, \
|
|
||||||
(strcmp(RelationGetRelationName(relation)->data, \
|
|
||||||
VariableRelationName) == 0) ? \
|
|
||||||
VariableRelationLockRelId \
|
|
||||||
: \
|
|
||||||
((LockInfo)(relation)->lockInfo)->lockRelId \
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
extern Oid LockRelIdGetRelationId(LockRelId lockRelId);
|
|
||||||
extern void RelationInitLockInfo(Relation relation);
|
extern void RelationInitLockInfo(Relation relation);
|
||||||
extern void RelationSetLockForDescriptorOpen(Relation relation);
|
extern void RelationSetLockForDescriptorOpen(Relation relation);
|
||||||
extern void RelationSetLockForRead(Relation relation);
|
extern void RelationSetLockForRead(Relation relation);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: lock.h,v 1.15 1998/06/30 02:33:33 momjian Exp $
|
* $Id: lock.h,v 1.16 1998/08/01 15:26:37 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -40,7 +40,11 @@ typedef int LOCKMODE;
|
|||||||
typedef int LOCKMETHOD;
|
typedef int LOCKMETHOD;
|
||||||
|
|
||||||
/* MAX_LOCKMODES cannot be larger than the bits in MASK */
|
/* MAX_LOCKMODES cannot be larger than the bits in MASK */
|
||||||
#define MAX_LOCKMODES 6
|
#ifdef LowLevelLocking
|
||||||
|
#define MAX_LOCKMODES 9
|
||||||
|
#else
|
||||||
|
#define MAX_LOCKMODES 6
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MAX_LOCK_METHODS corresponds to the number of spin locks allocated in
|
* MAX_LOCK_METHODS corresponds to the number of spin locks allocated in
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: multilev.h,v 1.11 1998/07/13 16:34:58 momjian Exp $
|
* $Id: multilev.h,v 1.12 1998/08/01 15:26:38 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -16,6 +16,24 @@
|
|||||||
|
|
||||||
#include <storage/lmgr.h>
|
#include <storage/lmgr.h>
|
||||||
|
|
||||||
|
#ifdef LowLevelLocking
|
||||||
|
|
||||||
|
/* DML locks */
|
||||||
|
#define RowShareLock 1 /* SELECT FOR UPDATE */
|
||||||
|
#define RowExclusiveLock 2 /* INSERT, UPDATE, DELETE */
|
||||||
|
#define ShareLock 3
|
||||||
|
#define ShareRowExclusiveLock 4
|
||||||
|
#define ExclusiveLock 5
|
||||||
|
|
||||||
|
/* DDL locks */
|
||||||
|
#define ObjShareLock 6
|
||||||
|
#define ObjExclusiveLock 7
|
||||||
|
|
||||||
|
/* Special locks */
|
||||||
|
#define ExtendLock 8
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#define READ_LOCK 2
|
#define READ_LOCK 2
|
||||||
#define WRITE_LOCK 1
|
#define WRITE_LOCK 1
|
||||||
|
|
||||||
@ -31,6 +49,8 @@
|
|||||||
|
|
||||||
#define EXTEND_LOCK 5
|
#define EXTEND_LOCK 5
|
||||||
|
|
||||||
|
#endif /* !LowLevelLocking */
|
||||||
|
|
||||||
#define SHORT_TERM 1
|
#define SHORT_TERM 1
|
||||||
#define LONG_TERM 2
|
#define LONG_TERM 2
|
||||||
#define UNLOCK 0
|
#define UNLOCK 0
|
||||||
|
Loading…
Reference in New Issue
Block a user