1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Clean up some longstanding problems in shared-cache invalidation.

SI messages now include the relevant database OID, so that operations
in one database do not cause useless cache flushes in backends attached
to other databases.  Declare SI messages properly using a union, to
eliminate the former assumption that Oid is the same size as int or Index.
Rewrite the nearly-unreadable code in inval.c, and document it better.
Arrange for catcache flushes at end of command/transaction to happen before
relcache flushes do --- this avoids loading a new tuple into the catcache
while setting up new relcache entry, only to have it be flushed again
immediately.
This commit is contained in:
Tom Lane
2001-06-19 19:42:16 +00:00
parent d9a069e224
commit bbbc00af88
10 changed files with 533 additions and 733 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.33 2001/06/16 22:58:13 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.34 2001/06/19 19:42:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -55,56 +55,31 @@ InitBackendSharedInvalidationState(void)
}
/*
* RegisterSharedInvalid
* SendSharedInvalidMessage
* Add a shared-cache-invalidation message to the global SI message queue.
*
* Note:
* Assumes hash index is valid.
* Assumes item pointer is valid.
*/
void
RegisterSharedInvalid(int cacheId, /* XXX */
Index hashIndex,
ItemPointer pointer)
SendSharedInvalidMessage(SharedInvalidationMessage *msg)
{
SharedInvalidData newInvalid;
bool insertOK;
/*
* This code has been hacked to accept two types of messages. This
* might be treated more generally in the future.
*
* (1) cacheId= system cache id hashIndex= system cache hash index for a
* (possibly) cached tuple pointer= pointer of (possibly) cached tuple
*
* (2) cacheId= special non-syscache id hashIndex= object id contained in
* (possibly) cached relation descriptor pointer= null
*/
newInvalid.cacheId = cacheId;
newInvalid.hashIndex = hashIndex;
if (ItemPointerIsValid(pointer))
ItemPointerCopy(pointer, &newInvalid.pointerData);
else
ItemPointerSetInvalid(&newInvalid.pointerData);
SpinAcquire(SInvalLock);
insertOK = SIInsertDataEntry(shmInvalBuffer, &newInvalid);
insertOK = SIInsertDataEntry(shmInvalBuffer, msg);
SpinRelease(SInvalLock);
if (!insertOK)
elog(DEBUG, "RegisterSharedInvalid: SI buffer overflow");
elog(DEBUG, "SendSharedInvalidMessage: SI buffer overflow");
}
/*
* InvalidateSharedInvalid
* ReceiveSharedInvalidMessages
* Process shared-cache-invalidation messages waiting for this backend
*/
void
InvalidateSharedInvalid(void (*invalFunction) (),
void (*resetFunction) ())
ReceiveSharedInvalidMessages(
void (*invalFunction) (SharedInvalidationMessage *msg),
void (*resetFunction) (void))
{
SharedInvalidData data;
SharedInvalidationMessage data;
int getResult;
bool gotMessage = false;
@@ -118,15 +93,13 @@ void
if (getResult < 0)
{
/* got a reset message */
elog(DEBUG, "InvalidateSharedInvalid: cache state reset");
elog(DEBUG, "ReceiveSharedInvalidMessages: cache state reset");
resetFunction();
}
else
{
/* got a normal data message */
invalFunction(data.cacheId,
data.hashIndex,
&data.pointerData);
invalFunction(&data);
}
gotMessage = true;
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.39 2001/06/16 22:58:15 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.40 2001/06/19 19:42:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,6 @@
#include "miscadmin.h"
#include "storage/backendid.h"
#include "storage/proc.h"
#include "storage/sinval.h"
#include "storage/sinvaladt.h"
SISeg *shmInvalBuffer;
@@ -35,7 +34,6 @@ static void SISetProcStateInvalid(SISeg *segP);
int
SInvalShmemSize(int maxBackends)
{
/*
* Figure space needed. Note sizeof(SISeg) includes the first
* ProcState entry.
@@ -183,14 +181,13 @@ CleanupInvalidationState(int status, Datum arg)
* Returns true for normal successful insertion, false if had to reset.
*/
bool
SIInsertDataEntry(SISeg *segP, SharedInvalidData *data)
SIInsertDataEntry(SISeg *segP, SharedInvalidationMessage *data)
{
int numMsgs = segP->maxMsgNum - segP->minMsgNum;
/* Is the buffer full? */
if (numMsgs >= MAXNUMMESSAGES)
{
/*
* Don't panic just yet: slowest backend might have consumed some
* messages but not yet have done SIDelExpiredDataEntries() to
@@ -273,13 +270,12 @@ SISetProcStateInvalid(SISeg *segP)
*/
int
SIGetDataEntry(SISeg *segP, int backendId,
SharedInvalidData *data)
SharedInvalidationMessage *data)
{
ProcState *stateP = &segP->procState[backendId - 1];
if (stateP->resetState)
{
/*
* Force reset. We can say we have dealt with any messages added
* since the reset, as well...

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.46 2001/06/12 05:55:49 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.47 2001/06/19 19:42:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -144,7 +144,7 @@ LockRelation(Relation relation, LOCKMODE lockmode)
* rebuild it and not just delete it.
*/
RelationIncrementReferenceCount(relation);
DiscardInvalid();
AcceptInvalidationMessages();
RelationDecrementReferenceCount(relation);
}