Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit bbbc00a

Browse files
committed
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.
1 parent d9a069e commit bbbc00a

File tree

10 files changed

+463
-663
lines changed

10 files changed

+463
-663
lines changed

src/backend/access/transam/xact.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.102 2001/05/04 18:39:16 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.103 2001/06/19 19:42:15 tgl Exp $
1212
*
1313
* NOTES
1414
* Transaction aborts can now occur two ways:
@@ -544,7 +544,6 @@ CommandCounterIncrement(void)
544544
*/
545545
AtCommit_LocalCache();
546546
AtStart_Cache();
547-
548547
}
549548

550549
void
@@ -577,7 +576,7 @@ InitializeTransactionSystem(void)
577576
static void
578577
AtStart_Cache(void)
579578
{
580-
DiscardInvalid();
579+
AcceptInvalidationMessages();
581580
}
582581

583582
/* --------------------------------
@@ -725,11 +724,10 @@ RecordTransactionCommit()
725724
static void
726725
AtCommit_Cache(void)
727726
{
728-
729727
/*
730-
* Make catalog changes visible to all backend.
728+
* Make catalog changes visible to all backends.
731729
*/
732-
RegisterInvalid(true);
730+
AtEOXactInvalidationMessages(true);
733731
}
734732

735733
/* --------------------------------
@@ -739,11 +737,10 @@ AtCommit_Cache(void)
739737
static void
740738
AtCommit_LocalCache(void)
741739
{
742-
743740
/*
744741
* Make catalog changes visible to me for the next command.
745742
*/
746-
ImmediateLocalInvalidation(true);
743+
CommandEndInvalidationMessages(true);
747744
}
748745

749746
/* --------------------------------
@@ -753,7 +750,6 @@ AtCommit_LocalCache(void)
753750
static void
754751
AtCommit_Locks(void)
755752
{
756-
757753
/*
758754
* XXX What if ProcReleaseLocks fails? (race condition?)
759755
*
@@ -769,7 +765,6 @@ AtCommit_Locks(void)
769765
static void
770766
AtCommit_Memory(void)
771767
{
772-
773768
/*
774769
* Now that we're "out" of a transaction, have the system allocate
775770
* things in the top memory context instead of per-transaction
@@ -844,7 +839,7 @@ static void
844839
AtAbort_Cache(void)
845840
{
846841
RelationCacheAbort();
847-
RegisterInvalid(false);
842+
AtEOXactInvalidationMessages(false);
848843
}
849844

850845
/* --------------------------------

src/backend/storage/ipc/sinval.c

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.33 2001/06/16 22:58:13 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.34 2001/06/19 19:42:15 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -55,56 +55,31 @@ InitBackendSharedInvalidationState(void)
5555
}
5656

5757
/*
58-
* RegisterSharedInvalid
58+
* SendSharedInvalidMessage
5959
* Add a shared-cache-invalidation message to the global SI message queue.
60-
*
61-
* Note:
62-
* Assumes hash index is valid.
63-
* Assumes item pointer is valid.
6460
*/
6561
void
66-
RegisterSharedInvalid(int cacheId, /* XXX */
67-
Index hashIndex,
68-
ItemPointer pointer)
62+
SendSharedInvalidMessage(SharedInvalidationMessage *msg)
6963
{
70-
SharedInvalidData newInvalid;
7164
bool insertOK;
7265

73-
/*
74-
* This code has been hacked to accept two types of messages. This
75-
* might be treated more generally in the future.
76-
*
77-
* (1) cacheId= system cache id hashIndex= system cache hash index for a
78-
* (possibly) cached tuple pointer= pointer of (possibly) cached tuple
79-
*
80-
* (2) cacheId= special non-syscache id hashIndex= object id contained in
81-
* (possibly) cached relation descriptor pointer= null
82-
*/
83-
84-
newInvalid.cacheId = cacheId;
85-
newInvalid.hashIndex = hashIndex;
86-
87-
if (ItemPointerIsValid(pointer))
88-
ItemPointerCopy(pointer, &newInvalid.pointerData);
89-
else
90-
ItemPointerSetInvalid(&newInvalid.pointerData);
91-
9266
SpinAcquire(SInvalLock);
93-
insertOK = SIInsertDataEntry(shmInvalBuffer, &newInvalid);
67+
insertOK = SIInsertDataEntry(shmInvalBuffer, msg);
9468
SpinRelease(SInvalLock);
9569
if (!insertOK)
96-
elog(DEBUG, "RegisterSharedInvalid: SI buffer overflow");
70+
elog(DEBUG, "SendSharedInvalidMessage: SI buffer overflow");
9771
}
9872

9973
/*
100-
* InvalidateSharedInvalid
74+
* ReceiveSharedInvalidMessages
10175
* Process shared-cache-invalidation messages waiting for this backend
10276
*/
10377
void
104-
InvalidateSharedInvalid(void (*invalFunction) (),
105-
void (*resetFunction) ())
78+
ReceiveSharedInvalidMessages(
79+
void (*invalFunction) (SharedInvalidationMessage *msg),
80+
void (*resetFunction) (void))
10681
{
107-
SharedInvalidData data;
82+
SharedInvalidationMessage data;
10883
int getResult;
10984
bool gotMessage = false;
11085

@@ -118,15 +93,13 @@ void
11893
if (getResult < 0)
11994
{
12095
/* got a reset message */
121-
elog(DEBUG, "InvalidateSharedInvalid: cache state reset");
96+
elog(DEBUG, "ReceiveSharedInvalidMessages: cache state reset");
12297
resetFunction();
12398
}
12499
else
125100
{
126101
/* got a normal data message */
127-
invalFunction(data.cacheId,
128-
data.hashIndex,
129-
&data.pointerData);
102+
invalFunction(&data);
130103
}
131104
gotMessage = true;
132105
}

src/backend/storage/ipc/sinvaladt.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.39 2001/06/16 22:58:15 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.40 2001/06/19 19:42:15 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -20,7 +20,6 @@
2020
#include "miscadmin.h"
2121
#include "storage/backendid.h"
2222
#include "storage/proc.h"
23-
#include "storage/sinval.h"
2423
#include "storage/sinvaladt.h"
2524

2625
SISeg *shmInvalBuffer;
@@ -35,7 +34,6 @@ static void SISetProcStateInvalid(SISeg *segP);
3534
int
3635
SInvalShmemSize(int maxBackends)
3736
{
38-
3937
/*
4038
* Figure space needed. Note sizeof(SISeg) includes the first
4139
* ProcState entry.
@@ -183,14 +181,13 @@ CleanupInvalidationState(int status, Datum arg)
183181
* Returns true for normal successful insertion, false if had to reset.
184182
*/
185183
bool
186-
SIInsertDataEntry(SISeg *segP, SharedInvalidData *data)
184+
SIInsertDataEntry(SISeg *segP, SharedInvalidationMessage *data)
187185
{
188186
int numMsgs = segP->maxMsgNum - segP->minMsgNum;
189187

190188
/* Is the buffer full? */
191189
if (numMsgs >= MAXNUMMESSAGES)
192190
{
193-
194191
/*
195192
* Don't panic just yet: slowest backend might have consumed some
196193
* messages but not yet have done SIDelExpiredDataEntries() to
@@ -273,13 +270,12 @@ SISetProcStateInvalid(SISeg *segP)
273270
*/
274271
int
275272
SIGetDataEntry(SISeg *segP, int backendId,
276-
SharedInvalidData *data)
273+
SharedInvalidationMessage *data)
277274
{
278275
ProcState *stateP = &segP->procState[backendId - 1];
279276

280277
if (stateP->resetState)
281278
{
282-
283279
/*
284280
* Force reset. We can say we have dealt with any messages added
285281
* since the reset, as well...

src/backend/storage/lmgr/lmgr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.46 2001/06/12 05:55:49 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.47 2001/06/19 19:42:16 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -144,7 +144,7 @@ LockRelation(Relation relation, LOCKMODE lockmode)
144144
* rebuild it and not just delete it.
145145
*/
146146
RelationIncrementReferenceCount(relation);
147-
DiscardInvalid();
147+
AcceptInvalidationMessages();
148148
RelationDecrementReferenceCount(relation);
149149
}
150150

src/backend/utils/cache/catcache.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.79 2001/06/18 03:35:07 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.80 2001/06/19 19:42:16 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -31,8 +31,18 @@
3131

3232
/* #define CACHEDEBUG */ /* turns DEBUG elogs on */
3333

34-
/* voodoo constants */
35-
#define NCCBUCKETS 257 /* Hash buckets per CatCache (prime!) */
34+
/*
35+
* Constants related to size of the catcache.
36+
*
37+
* NCCBUCKETS should be prime and must be less than 64K (because
38+
* SharedInvalCatcacheMsg crams hash indexes into a uint16 field). In
39+
* practice it should be a lot less, anyway, to avoid chewing up too much
40+
* space on hash bucket headers.
41+
*
42+
* MAXCCTUPLES could be as small as a few hundred, if per-backend memory
43+
* consumption is at a premium.
44+
*/
45+
#define NCCBUCKETS 257 /* Hash buckets per CatCache */
3646
#define MAXCCTUPLES 5000 /* Maximum # of tuples in all caches */
3747

3848

@@ -218,6 +228,11 @@ CatalogCacheInitializeCache(CatCache *cache)
218228
*/
219229
tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation));
220230

231+
/*
232+
* get the relation's relisshared flag, too
233+
*/
234+
cache->cc_relisshared = RelationGetForm(relation)->relisshared;
235+
221236
/*
222237
* return to the caller's memory context and close the rel
223238
*/
@@ -737,6 +752,7 @@ InitCatCache(int id,
737752
cp->cc_relname = relname;
738753
cp->cc_indname = indname;
739754
cp->cc_reloidattr = reloidattr;
755+
cp->cc_relisshared = false; /* temporary */
740756
cp->cc_tupdesc = (TupleDesc) NULL;
741757
cp->cc_ntup = 0;
742758
cp->cc_size = NCCBUCKETS;
@@ -1116,7 +1132,8 @@ ReleaseCatCache(HeapTuple tuple)
11161132
*
11171133
* Note that it is irrelevant whether the given tuple is actually loaded
11181134
* into the catcache at the moment. Even if it's not there now, it might
1119-
* be by the end of the command, so we have to be prepared to flush it.
1135+
* be by the end of the command --- or might be in other backends' caches
1136+
* --- so we have to be prepared to flush it.
11201137
*
11211138
* Also note that it's not an error if there are no catcaches for the
11221139
* specified relation. inval.c doesn't know exactly which rels have
@@ -1126,7 +1143,7 @@ ReleaseCatCache(HeapTuple tuple)
11261143
void
11271144
PrepareToInvalidateCacheTuple(Relation relation,
11281145
HeapTuple tuple,
1129-
void (*function) (int, Index, ItemPointer))
1146+
void (*function) (int, Index, ItemPointer, Oid))
11301147
{
11311148
CatCache *ccp;
11321149

@@ -1159,6 +1176,7 @@ PrepareToInvalidateCacheTuple(Relation relation,
11591176

11601177
(*function) (ccp->id,
11611178
CatalogCacheComputeTupleHashIndex(ccp, tuple),
1162-
&tuple->t_self);
1179+
&tuple->t_self,
1180+
ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId);
11631181
}
11641182
}

0 commit comments

Comments
 (0)