PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
inval.c File Reference
#include "postgres.h"
#include <limits.h>
#include "access/htup_details.h"
#include "access/xact.h"
#include "access/xloginsert.h"
#include "catalog/catalog.h"
#include "catalog/pg_constraint.h"
#include "miscadmin.h"
#include "storage/procnumber.h"
#include "storage/sinval.h"
#include "storage/smgr.h"
#include "utils/catcache.h"
#include "utils/injection_point.h"
#include "utils/inval.h"
#include "utils/memdebug.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
Include dependency graph for inval.c:

Go to the source code of this file.

Data Structures

struct  InvalMessageArray
 
struct  InvalidationMsgsGroup
 
struct  InvalidationInfo
 
struct  TransInvalidationInfo
 
struct  SYSCACHECALLBACK
 
struct  RELCACHECALLBACK
 
struct  RELSYNCCALLBACK
 

Macros

#define CatCacheMsgs   0
 
#define RelCacheMsgs   1
 
#define SetSubGroupToFollow(targetgroup, priorgroup, subgroup)
 
#define SetGroupToFollow(targetgroup, priorgroup)
 
#define NumMessagesInSubGroup(group, subgroup)    ((group)->nextmsg[subgroup] - (group)->firstmsg[subgroup])
 
#define NumMessagesInGroup(group)
 
#define MAX_SYSCACHE_CALLBACKS   64
 
#define MAX_RELCACHE_CALLBACKS   10
 
#define MAX_RELSYNC_CALLBACKS   10
 
#define ProcessMessageSubGroup(group, subgroup, codeFragment)
 
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
 

Typedefs

typedef struct InvalMessageArray InvalMessageArray
 
typedef struct InvalidationMsgsGroup InvalidationMsgsGroup
 
typedef struct InvalidationInfo InvalidationInfo
 
typedef struct TransInvalidationInfo TransInvalidationInfo
 

Functions

static void AddInvalidationMessage (InvalidationMsgsGroup *group, int subgroup, const SharedInvalidationMessage *msg)
 
static void AppendInvalidationMessageSubGroup (InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src, int subgroup)
 
static void AddCatcacheInvalidationMessage (InvalidationMsgsGroup *group, int id, uint32 hashValue, Oid dbId)
 
static void AddCatalogInvalidationMessage (InvalidationMsgsGroup *group, Oid dbId, Oid catId)
 
static void AddRelcacheInvalidationMessage (InvalidationMsgsGroup *group, Oid dbId, Oid relId)
 
static void AddRelsyncInvalidationMessage (InvalidationMsgsGroup *group, Oid dbId, Oid relId)
 
static void AddSnapshotInvalidationMessage (InvalidationMsgsGroup *group, Oid dbId, Oid relId)
 
static void AppendInvalidationMessages (InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src)
 
static void ProcessInvalidationMessages (InvalidationMsgsGroup *group, void(*func)(SharedInvalidationMessage *msg))
 
static void ProcessInvalidationMessagesMulti (InvalidationMsgsGroup *group, void(*func)(const SharedInvalidationMessage *msgs, int n))
 
static void RegisterCatcacheInvalidation (int cacheId, uint32 hashValue, Oid dbId, void *context)
 
static void RegisterCatalogInvalidation (InvalidationInfo *info, Oid dbId, Oid catId)
 
static void RegisterRelcacheInvalidation (InvalidationInfo *info, Oid dbId, Oid relId)
 
static void RegisterRelsyncInvalidation (InvalidationInfo *info, Oid dbId, Oid relId)
 
static void RegisterSnapshotInvalidation (InvalidationInfo *info, Oid dbId, Oid relId)
 
static InvalidationInfoPrepareInvalidationState (void)
 
static InvalidationInfoPrepareInplaceInvalidationState (void)
 
void InvalidateSystemCachesExtended (bool debug_discard)
 
void LocalExecuteInvalidationMessage (SharedInvalidationMessage *msg)
 
void InvalidateSystemCaches (void)
 
void AcceptInvalidationMessages (void)
 
void PostPrepare_Inval (void)
 
int xactGetCommittedInvalidationMessages (SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
 
int inplaceGetInvalidationMessages (SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
 
void ProcessCommittedInvalidationMessages (SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
 
void AtEOXact_Inval (bool isCommit)
 
void PreInplace_Inval (void)
 
void AtInplace_Inval (void)
 
void ForgetInplace_Inval (void)
 
void AtEOSubXact_Inval (bool isCommit)
 
void CommandEndInvalidationMessages (void)
 
static void CacheInvalidateHeapTupleCommon (Relation relation, HeapTuple tuple, HeapTuple newtuple, InvalidationInfo *(*prepare_callback)(void))
 
void CacheInvalidateHeapTuple (Relation relation, HeapTuple tuple, HeapTuple newtuple)
 
void CacheInvalidateHeapTupleInplace (Relation relation, HeapTuple tuple, HeapTuple newtuple)
 
void CacheInvalidateCatalog (Oid catalogId)
 
void CacheInvalidateRelcache (Relation relation)
 
void CacheInvalidateRelcacheAll (void)
 
void CacheInvalidateRelcacheByTuple (HeapTuple classTuple)
 
void CacheInvalidateRelcacheByRelid (Oid relid)
 
void CacheInvalidateRelSync (Oid relid)
 
void CacheInvalidateRelSyncAll (void)
 
void CacheInvalidateSmgr (RelFileLocatorBackend rlocator)
 
void CacheInvalidateRelmap (Oid databaseId)
 
void CacheRegisterSyscacheCallback (int cacheid, SyscacheCallbackFunction func, Datum arg)
 
void CacheRegisterRelcacheCallback (RelcacheCallbackFunction func, Datum arg)
 
void CacheRegisterRelSyncCallback (RelSyncCallbackFunction func, Datum arg)
 
void CallSyscacheCallbacks (int cacheid, uint32 hashvalue)
 
void CallRelSyncCallbacks (Oid relid)
 
void LogLogicalInvalidations (void)
 

Variables

static InvalMessageArray InvalMessageArrays [2]
 
static TransInvalidationInfotransInvalInfo = NULL
 
static InvalidationInfoinplaceInvalInfo = NULL
 
int debug_discard_caches = 0
 
static struct SYSCACHECALLBACK syscache_callback_list [MAX_SYSCACHE_CALLBACKS]
 
static int16 syscache_callback_links [SysCacheSize]
 
static int syscache_callback_count = 0
 
static struct RELCACHECALLBACK relcache_callback_list [MAX_RELCACHE_CALLBACKS]
 
static int relcache_callback_count = 0
 
static struct RELSYNCCALLBACK relsync_callback_list [MAX_RELSYNC_CALLBACKS]
 
static int relsync_callback_count = 0
 

Macro Definition Documentation

◆ CatCacheMsgs

#define CatCacheMsgs   0

Definition at line 171 of file inval.c.

◆ MAX_RELCACHE_CALLBACKS

#define MAX_RELCACHE_CALLBACKS   10

Definition at line 273 of file inval.c.

◆ MAX_RELSYNC_CALLBACKS

#define MAX_RELSYNC_CALLBACKS   10

Definition at line 274 of file inval.c.

◆ MAX_SYSCACHE_CALLBACKS

#define MAX_SYSCACHE_CALLBACKS   64

Definition at line 272 of file inval.c.

◆ NumMessagesInGroup

#define NumMessagesInGroup (   group)
Value:
NumMessagesInSubGroup(group, RelCacheMsgs))
#define CatCacheMsgs
Definition: inval.c:171
#define NumMessagesInSubGroup(group, subgroup)
Definition: inval.c:204
#define RelCacheMsgs
Definition: inval.c:172

Definition at line 207 of file inval.c.

◆ NumMessagesInSubGroup

#define NumMessagesInSubGroup (   group,
  subgroup 
)     ((group)->nextmsg[subgroup] - (group)->firstmsg[subgroup])

Definition at line 204 of file inval.c.

◆ ProcessMessageSubGroup

#define ProcessMessageSubGroup (   group,
  subgroup,
  codeFragment 
)
Value:
do { \
int _msgindex = (group)->firstmsg[subgroup]; \
int _endmsg = (group)->nextmsg[subgroup]; \
for (; _msgindex < _endmsg; _msgindex++) \
{ \
SharedInvalidationMessage *msg = \
&InvalMessageArrays[subgroup].msgs[_msgindex]; \
codeFragment; \
} \
} while (0)
static InvalMessageArray InvalMessageArrays[2]
Definition: inval.c:181
SharedInvalidationMessage * msgs
Definition: inval.c:177

Definition at line 384 of file inval.c.

◆ ProcessMessageSubGroupMulti

#define ProcessMessageSubGroupMulti (   group,
  subgroup,
  codeFragment 
)
Value:
do { \
int n = NumMessagesInSubGroup(group, subgroup); \
if (n > 0) { \
SharedInvalidationMessage *msgs = \
&InvalMessageArrays[subgroup].msgs[(group)->firstmsg[subgroup]]; \
codeFragment; \
} \
} while (0)

Definition at line 402 of file inval.c.

◆ RelCacheMsgs

#define RelCacheMsgs   1

Definition at line 172 of file inval.c.

◆ SetGroupToFollow

#define SetGroupToFollow (   targetgroup,
  priorgroup 
)
Value:
do { \
SetSubGroupToFollow(targetgroup, priorgroup, CatCacheMsgs); \
SetSubGroupToFollow(targetgroup, priorgroup, RelCacheMsgs); \
} while (0)

Definition at line 198 of file inval.c.

◆ SetSubGroupToFollow

#define SetSubGroupToFollow (   targetgroup,
  priorgroup,
  subgroup 
)
Value:
do { \
(targetgroup)->firstmsg[subgroup] = \
(targetgroup)->nextmsg[subgroup] = \
(priorgroup)->nextmsg[subgroup]; \
} while (0)

Definition at line 191 of file inval.c.

Typedef Documentation

◆ InvalidationInfo

◆ InvalidationMsgsGroup

◆ InvalMessageArray

◆ TransInvalidationInfo

Function Documentation

◆ AcceptInvalidationMessages()

void AcceptInvalidationMessages ( void  )

Definition at line 929 of file inval.c.

930{
933
934 /*----------
935 * Test code to force cache flushes anytime a flush could happen.
936 *
937 * This helps detect intermittent faults caused by code that reads a cache
938 * entry and then performs an action that could invalidate the entry, but
939 * rarely actually does so. This can spot issues that would otherwise
940 * only arise with badly timed concurrent DDL, for example.
941 *
942 * The default debug_discard_caches = 0 does no forced cache flushes.
943 *
944 * If used with CLOBBER_FREED_MEMORY,
945 * debug_discard_caches = 1 (formerly known as CLOBBER_CACHE_ALWAYS)
946 * provides a fairly thorough test that the system contains no cache-flush
947 * hazards. However, it also makes the system unbelievably slow --- the
948 * regression tests take about 100 times longer than normal.
949 *
950 * If you're a glutton for punishment, try
951 * debug_discard_caches = 3 (formerly known as CLOBBER_CACHE_RECURSIVELY).
952 * This slows things by at least a factor of 10000, so I wouldn't suggest
953 * trying to run the entire regression tests that way. It's useful to try
954 * a few simple tests, to make sure that cache reload isn't subject to
955 * internal cache-flush hazards, but after you've done a few thousand
956 * recursive reloads it's unlikely you'll learn more.
957 *----------
958 */
959#ifdef DISCARD_CACHES_ENABLED
960 {
961 static int recursion_depth = 0;
962
964 {
968 }
969 }
970#endif
971}
static int recursion_depth
Definition: elog.c:150
void InvalidateSystemCachesExtended(bool debug_discard)
Definition: inval.c:784
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:822
void InvalidateSystemCaches(void)
Definition: inval.c:915
int debug_discard_caches
Definition: inval.c:260
void ReceiveSharedInvalidMessages(void(*invalFunction)(SharedInvalidationMessage *msg), void(*resetFunction)(void))
Definition: sinval.c:69

References debug_discard_caches, InvalidateSystemCaches(), InvalidateSystemCachesExtended(), LocalExecuteInvalidationMessage(), ReceiveSharedInvalidMessages(), and recursion_depth.

Referenced by apply_handle_commit_internal(), AtStart_Cache(), ConditionalLockDatabaseObject(), ConditionalLockRelation(), ConditionalLockRelationOid(), ConditionalLockSharedObject(), delay_execution_planner(), heap_inplace_update_and_unlock(), InitializeSessionUserId(), LockDatabaseObject(), LockRelation(), LockRelationId(), LockRelationOid(), LockSharedObject(), LogicalRepApplyLoop(), pgstat_init_function_usage(), ProcessCatchupInterrupt(), RangeVarGetRelidExtended(), relation_openrv(), relation_openrv_extended(), RelationBuildPartitionDesc(), RemoveRelations(), SearchSysCacheLocked1(), and write_relcache_init_file().

◆ AddCatalogInvalidationMessage()

static void AddCatalogInvalidationMessage ( InvalidationMsgsGroup group,
Oid  dbId,
Oid  catId 
)
static

Definition at line 453 of file inval.c.

455{
457
459 msg.cat.dbId = dbId;
460 msg.cat.catId = catId;
461 /* check AddCatcacheInvalidationMessage() for an explanation */
462 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
463
465}
static void AddInvalidationMessage(InvalidationMsgsGroup *group, int subgroup, const SharedInvalidationMessage *msg)
Definition: inval.c:320
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
#define SHAREDINVALCATALOG_ID
Definition: sinval.h:68
SharedInvalCatalogMsg cat
Definition: sinval.h:128

References AddInvalidationMessage(), SharedInvalidationMessage::cat, CatCacheMsgs, SharedInvalCatalogMsg::catId, SharedInvalCatalogMsg::dbId, SharedInvalCatalogMsg::id, SHAREDINVALCATALOG_ID, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by RegisterCatalogInvalidation().

◆ AddCatcacheInvalidationMessage()

static void AddCatcacheInvalidationMessage ( InvalidationMsgsGroup group,
int  id,
uint32  hashValue,
Oid  dbId 
)
static

Definition at line 425 of file inval.c.

427{
429
430 Assert(id < CHAR_MAX);
431 msg.cc.id = (int8) id;
432 msg.cc.dbId = dbId;
433 msg.cc.hashValue = hashValue;
434
435 /*
436 * Define padding bytes in SharedInvalidationMessage structs to be
437 * defined. Otherwise the sinvaladt.c ringbuffer, which is accessed by
438 * multiple processes, will cause spurious valgrind warnings about
439 * undefined memory being used. That's because valgrind remembers the
440 * undefined bytes from the last local process's store, not realizing that
441 * another process has written since, filling the previously uninitialized
442 * bytes
443 */
444 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
445
447}
int8_t int8
Definition: c.h:496
Assert(PointerIsAligned(start, uint64))
SharedInvalCatcacheMsg cc
Definition: sinval.h:127

References AddInvalidationMessage(), Assert(), CatCacheMsgs, SharedInvalidationMessage::cc, SharedInvalCatcacheMsg::dbId, SharedInvalCatcacheMsg::hashValue, SharedInvalCatcacheMsg::id, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by RegisterCatcacheInvalidation().

◆ AddInvalidationMessage()

static void AddInvalidationMessage ( InvalidationMsgsGroup group,
int  subgroup,
const SharedInvalidationMessage msg 
)
static

Definition at line 320 of file inval.c.

322{
323 InvalMessageArray *ima = &InvalMessageArrays[subgroup];
324 int nextindex = group->nextmsg[subgroup];
325
326 if (nextindex >= ima->maxmsgs)
327 {
328 if (ima->msgs == NULL)
329 {
330 /* Create new storage array in TopTransactionContext */
331 int reqsize = 32; /* arbitrary */
332
335 reqsize * sizeof(SharedInvalidationMessage));
336 ima->maxmsgs = reqsize;
337 Assert(nextindex == 0);
338 }
339 else
340 {
341 /* Enlarge storage array */
342 int reqsize = 2 * ima->maxmsgs;
343
345 repalloc(ima->msgs,
346 reqsize * sizeof(SharedInvalidationMessage));
347 ima->maxmsgs = reqsize;
348 }
349 }
350 /* Okay, add message to current group */
351 ima->msgs[nextindex] = *msg;
352 group->nextmsg[subgroup]++;
353}
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1256
MemoryContext TopTransactionContext
Definition: mcxt.c:170
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:2167

References Assert(), InvalMessageArrays, InvalMessageArray::maxmsgs, MemoryContextAlloc(), InvalMessageArray::msgs, InvalidationMsgsGroup::nextmsg, repalloc(), and TopTransactionContext.

Referenced by AddCatalogInvalidationMessage(), AddCatcacheInvalidationMessage(), AddRelcacheInvalidationMessage(), AddRelsyncInvalidationMessage(), and AddSnapshotInvalidationMessage().

◆ AddRelcacheInvalidationMessage()

static void AddRelcacheInvalidationMessage ( InvalidationMsgsGroup group,
Oid  dbId,
Oid  relId 
)
static

Definition at line 471 of file inval.c.

473{
475
476 /*
477 * Don't add a duplicate item. We assume dbId need not be checked because
478 * it will never change. InvalidOid for relId means all relations so we
479 * don't need to add individual ones when it is present.
480 */
482 if (msg->rc.id == SHAREDINVALRELCACHE_ID &&
483 (msg->rc.relId == relId ||
484 msg->rc.relId == InvalidOid))
485 return);
486
487 /* OK, add the item */
489 msg.rc.dbId = dbId;
490 msg.rc.relId = relId;
491 /* check AddCatcacheInvalidationMessage() for an explanation */
492 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
493
495}
#define ProcessMessageSubGroup(group, subgroup, codeFragment)
Definition: inval.c:384
#define InvalidOid
Definition: postgres_ext.h:35
#define SHAREDINVALRELCACHE_ID
Definition: sinval.h:77
SharedInvalRelcacheMsg rc
Definition: sinval.h:129

References AddInvalidationMessage(), SharedInvalRelcacheMsg::dbId, SharedInvalRelcacheMsg::id, InvalidOid, ProcessMessageSubGroup, SharedInvalidationMessage::rc, RelCacheMsgs, SharedInvalRelcacheMsg::relId, SHAREDINVALRELCACHE_ID, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by RegisterRelcacheInvalidation().

◆ AddRelsyncInvalidationMessage()

static void AddRelsyncInvalidationMessage ( InvalidationMsgsGroup group,
Oid  dbId,
Oid  relId 
)
static

Definition at line 505 of file inval.c.

507{
509
510 /* Don't add a duplicate item. */
512 if (msg->rc.id == SHAREDINVALRELSYNC_ID &&
513 (msg->rc.relId == relId ||
514 msg->rc.relId == InvalidOid))
515 return);
516
517 /* OK, add the item */
519 msg.rc.dbId = dbId;
520 msg.rc.relId = relId;
521 /* check AddCatcacheInvalidationMessage() for an explanation */
522 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
523
525}
#define SHAREDINVALRELSYNC_ID
Definition: sinval.h:114

References AddInvalidationMessage(), SharedInvalRelcacheMsg::dbId, SharedInvalRelcacheMsg::id, InvalidOid, ProcessMessageSubGroup, SharedInvalidationMessage::rc, RelCacheMsgs, SharedInvalRelcacheMsg::relId, SHAREDINVALRELSYNC_ID, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by RegisterRelsyncInvalidation().

◆ AddSnapshotInvalidationMessage()

static void AddSnapshotInvalidationMessage ( InvalidationMsgsGroup group,
Oid  dbId,
Oid  relId 
)
static

Definition at line 533 of file inval.c.

535{
537
538 /* Don't add a duplicate item */
539 /* We assume dbId need not be checked because it will never change */
541 if (msg->sn.id == SHAREDINVALSNAPSHOT_ID &&
542 msg->sn.relId == relId)
543 return);
544
545 /* OK, add the item */
547 msg.sn.dbId = dbId;
548 msg.sn.relId = relId;
549 /* check AddCatcacheInvalidationMessage() for an explanation */
550 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
551
553}
#define SHAREDINVALSNAPSHOT_ID
Definition: sinval.h:105
SharedInvalSnapshotMsg sn
Definition: sinval.h:132

References AddInvalidationMessage(), SharedInvalSnapshotMsg::dbId, SharedInvalSnapshotMsg::id, ProcessMessageSubGroup, RelCacheMsgs, SharedInvalSnapshotMsg::relId, SHAREDINVALSNAPSHOT_ID, SharedInvalidationMessage::sn, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by RegisterSnapshotInvalidation().

◆ AppendInvalidationMessages()

static void AppendInvalidationMessages ( InvalidationMsgsGroup dest,
InvalidationMsgsGroup src 
)
static

Definition at line 560 of file inval.c.

562{
565}
static void AppendInvalidationMessageSubGroup(InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src, int subgroup)
Definition: inval.c:360

References AppendInvalidationMessageSubGroup(), CatCacheMsgs, generate_unaccent_rules::dest, and RelCacheMsgs.

Referenced by AtEOSubXact_Inval(), AtEOXact_Inval(), and CommandEndInvalidationMessages().

◆ AppendInvalidationMessageSubGroup()

static void AppendInvalidationMessageSubGroup ( InvalidationMsgsGroup dest,
InvalidationMsgsGroup src,
int  subgroup 
)
static

Definition at line 360 of file inval.c.

363{
364 /* Messages must be adjacent in main array */
365 Assert(dest->nextmsg[subgroup] == src->firstmsg[subgroup]);
366
367 /* ... which makes this easy: */
368 dest->nextmsg[subgroup] = src->nextmsg[subgroup];
369
370 /*
371 * This is handy for some callers and irrelevant for others. But we do it
372 * always, reasoning that it's bad to leave different groups pointing at
373 * the same fragment of the message array.
374 */
375 SetSubGroupToFollow(src, dest, subgroup);
376}
#define SetSubGroupToFollow(targetgroup, priorgroup, subgroup)
Definition: inval.c:191

References Assert(), generate_unaccent_rules::dest, InvalidationMsgsGroup::firstmsg, InvalidationMsgsGroup::nextmsg, and SetSubGroupToFollow.

Referenced by AppendInvalidationMessages().

◆ AtEOSubXact_Inval()

void AtEOSubXact_Inval ( bool  isCommit)

Definition at line 1303 of file inval.c.

1304{
1305 int my_level;
1306 TransInvalidationInfo *myInfo;
1307
1308 /*
1309 * Successful inplace update must clear this, but we clear it on abort.
1310 * Inplace updates allocate this in CurrentMemoryContext, which has
1311 * lifespan <= subtransaction lifespan. Hence, don't free it explicitly.
1312 */
1313 if (isCommit)
1314 Assert(inplaceInvalInfo == NULL);
1315 else
1316 inplaceInvalInfo = NULL;
1317
1318 /* Quick exit if no transactional messages. */
1319 myInfo = transInvalInfo;
1320 if (myInfo == NULL)
1321 return;
1322
1323 /* Also bail out quickly if messages are not for this level. */
1324 my_level = GetCurrentTransactionNestLevel();
1325 if (myInfo->my_level != my_level)
1326 {
1327 Assert(myInfo->my_level < my_level);
1328 return;
1329 }
1330
1331 if (isCommit)
1332 {
1333 /* If CurrentCmdInvalidMsgs still has anything, fix it */
1335
1336 /*
1337 * We create invalidation stack entries lazily, so the parent might
1338 * not have one. Instead of creating one, moving all the data over,
1339 * and then freeing our own, we can just adjust the level of our own
1340 * entry.
1341 */
1342 if (myInfo->parent == NULL || myInfo->parent->my_level < my_level - 1)
1343 {
1344 myInfo->my_level--;
1345 return;
1346 }
1347
1348 /*
1349 * Pass up my inval messages to parent. Notice that we stick them in
1350 * PriorCmdInvalidMsgs, not CurrentCmdInvalidMsgs, since they've
1351 * already been locally processed. (This would trigger the Assert in
1352 * AppendInvalidationMessageSubGroup if the parent's
1353 * CurrentCmdInvalidMsgs isn't empty; but we already checked that in
1354 * PrepareInvalidationState.)
1355 */
1357 &myInfo->PriorCmdInvalidMsgs);
1358
1359 /* Must readjust parent's CurrentCmdInvalidMsgs indexes now */
1361 &myInfo->parent->PriorCmdInvalidMsgs);
1362
1363 /* Pending relcache inval becomes parent's problem too */
1364 if (myInfo->ii.RelcacheInitFileInval)
1365 myInfo->parent->ii.RelcacheInitFileInval = true;
1366
1367 /* Pop the transaction state stack */
1368 transInvalInfo = myInfo->parent;
1369
1370 /* Need not free anything else explicitly */
1371 pfree(myInfo);
1372 }
1373 else
1374 {
1377
1378 /* Pop the transaction state stack */
1379 transInvalInfo = myInfo->parent;
1380
1381 /* Need not free anything else explicitly */
1382 pfree(myInfo);
1383 }
1384}
static void ProcessInvalidationMessages(InvalidationMsgsGroup *group, void(*func)(SharedInvalidationMessage *msg))
Definition: inval.c:574
static InvalidationInfo * inplaceInvalInfo
Definition: inval.c:257
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:255
static void AppendInvalidationMessages(InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src)
Definition: inval.c:560
#define SetGroupToFollow(targetgroup, priorgroup)
Definition: inval.c:198
void CommandEndInvalidationMessages(void)
Definition: inval.c:1402
void pfree(void *pointer)
Definition: mcxt.c:2147
bool RelcacheInitFileInval
Definition: inval.c:236
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:233
struct TransInvalidationInfo * parent
Definition: inval.c:249
struct InvalidationInfo ii
Definition: inval.c:243
InvalidationMsgsGroup PriorCmdInvalidMsgs
Definition: inval.c:246
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:929

References AppendInvalidationMessages(), Assert(), CommandEndInvalidationMessages(), InvalidationInfo::CurrentCmdInvalidMsgs, GetCurrentTransactionNestLevel(), TransInvalidationInfo::ii, inplaceInvalInfo, LocalExecuteInvalidationMessage(), TransInvalidationInfo::my_level, TransInvalidationInfo::parent, pfree(), TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessInvalidationMessages(), InvalidationInfo::RelcacheInitFileInval, SetGroupToFollow, and transInvalInfo.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Inval()

void AtEOXact_Inval ( bool  isCommit)

Definition at line 1192 of file inval.c.

1193{
1194 inplaceInvalInfo = NULL;
1195
1196 /* Quick exit if no transactional messages */
1197 if (transInvalInfo == NULL)
1198 return;
1199
1200 /* Must be at top of stack */
1202
1203 INJECTION_POINT("AtEOXact_Inval-with-transInvalInfo");
1204
1205 if (isCommit)
1206 {
1207 /*
1208 * Relcache init file invalidation requires processing both before and
1209 * after we send the SI messages. However, we need not do anything
1210 * unless we committed.
1211 */
1214
1217
1220
1223 }
1224 else
1225 {
1228 }
1229
1230 /* Need not free anything explicitly */
1231 transInvalInfo = NULL;
1232}
#define INJECTION_POINT(name)
static void ProcessInvalidationMessagesMulti(InvalidationMsgsGroup *group, void(*func)(const SharedInvalidationMessage *msgs, int n))
Definition: inval.c:586
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6868
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6843
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:47

References AppendInvalidationMessages(), Assert(), InvalidationInfo::CurrentCmdInvalidMsgs, TransInvalidationInfo::ii, INJECTION_POINT, inplaceInvalInfo, LocalExecuteInvalidationMessage(), TransInvalidationInfo::my_level, TransInvalidationInfo::parent, TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessInvalidationMessages(), ProcessInvalidationMessagesMulti(), RelationCacheInitFilePostInvalidate(), RelationCacheInitFilePreInvalidate(), InvalidationInfo::RelcacheInitFileInval, SendSharedInvalidMessages(), and transInvalInfo.

Referenced by AbortTransaction(), CommitTransaction(), and PostPrepare_Inval().

◆ AtInplace_Inval()

◆ CacheInvalidateCatalog()

void CacheInvalidateCatalog ( Oid  catalogId)

Definition at line 1598 of file inval.c.

1599{
1600 Oid databaseId;
1601
1602 if (IsSharedRelation(catalogId))
1603 databaseId = InvalidOid;
1604 else
1605 databaseId = MyDatabaseId;
1606
1608 databaseId, catalogId);
1609}
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:273
Oid MyDatabaseId
Definition: globals.c:95
static InvalidationInfo * PrepareInvalidationState(void)
Definition: inval.c:682
static void RegisterCatalogInvalidation(InvalidationInfo *info, Oid dbId, Oid catId)
Definition: inval.c:621
unsigned int Oid
Definition: postgres_ext.h:30

References InvalidOid, IsSharedRelation(), MyDatabaseId, PrepareInvalidationState(), and RegisterCatalogInvalidation().

Referenced by finish_heap_swap().

◆ CacheInvalidateHeapTuple()

void CacheInvalidateHeapTuple ( Relation  relation,
HeapTuple  tuple,
HeapTuple  newtuple 
)

Definition at line 1561 of file inval.c.

1564{
1565 CacheInvalidateHeapTupleCommon(relation, tuple, newtuple,
1567}
static void CacheInvalidateHeapTupleCommon(Relation relation, HeapTuple tuple, HeapTuple newtuple, InvalidationInfo *(*prepare_callback)(void))
Definition: inval.c:1429

References CacheInvalidateHeapTupleCommon(), and PrepareInvalidationState().

Referenced by AlterDomainAddConstraint(), AlterDomainDropConstraint(), heap_delete(), heap_inplace_update_and_unlock(), heap_insert(), heap_multi_insert(), and heap_update().

◆ CacheInvalidateHeapTupleCommon()

static void CacheInvalidateHeapTupleCommon ( Relation  relation,
HeapTuple  tuple,
HeapTuple  newtuple,
InvalidationInfo *(*)(void)  prepare_callback 
)
static

Definition at line 1429 of file inval.c.

1433{
1434 InvalidationInfo *info;
1435 Oid tupleRelId;
1436 Oid databaseId;
1437 Oid relationId;
1438
1439 /* Do nothing during bootstrap */
1441 return;
1442
1443 /*
1444 * We only need to worry about invalidation for tuples that are in system
1445 * catalogs; user-relation tuples are never in catcaches and can't affect
1446 * the relcache either.
1447 */
1448 if (!IsCatalogRelation(relation))
1449 return;
1450
1451 /*
1452 * IsCatalogRelation() will return true for TOAST tables of system
1453 * catalogs, but we don't care about those, either.
1454 */
1455 if (IsToastRelation(relation))
1456 return;
1457
1458 /* Allocate any required resources. */
1459 info = prepare_callback();
1460
1461 /*
1462 * First let the catcache do its thing
1463 */
1464 tupleRelId = RelationGetRelid(relation);
1465 if (RelationInvalidatesSnapshotsOnly(tupleRelId))
1466 {
1467 databaseId = IsSharedRelation(tupleRelId) ? InvalidOid : MyDatabaseId;
1468 RegisterSnapshotInvalidation(info, databaseId, tupleRelId);
1469 }
1470 else
1471 PrepareToInvalidateCacheTuple(relation, tuple, newtuple,
1473 (void *) info);
1474
1475 /*
1476 * Now, is this tuple one of the primary definers of a relcache entry? See
1477 * comments in file header for deeper explanation.
1478 *
1479 * Note we ignore newtuple here; we assume an update cannot move a tuple
1480 * from being part of one relcache entry to being part of another.
1481 */
1482 if (tupleRelId == RelationRelationId)
1483 {
1484 Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple);
1485
1486 relationId = classtup->oid;
1487 if (classtup->relisshared)
1488 databaseId = InvalidOid;
1489 else
1490 databaseId = MyDatabaseId;
1491 }
1492 else if (tupleRelId == AttributeRelationId)
1493 {
1495
1496 relationId = atttup->attrelid;
1497
1498 /*
1499 * KLUGE ALERT: we always send the relcache event with MyDatabaseId,
1500 * even if the rel in question is shared (which we can't easily tell).
1501 * This essentially means that only backends in this same database
1502 * will react to the relcache flush request. This is in fact
1503 * appropriate, since only those backends could see our pg_attribute
1504 * change anyway. It looks a bit ugly though. (In practice, shared
1505 * relations can't have schema changes after bootstrap, so we should
1506 * never come here for a shared rel anyway.)
1507 */
1508 databaseId = MyDatabaseId;
1509 }
1510 else if (tupleRelId == IndexRelationId)
1511 {
1512 Form_pg_index indextup = (Form_pg_index) GETSTRUCT(tuple);
1513
1514 /*
1515 * When a pg_index row is updated, we should send out a relcache inval
1516 * for the index relation. As above, we don't know the shared status
1517 * of the index, but in practice it doesn't matter since indexes of
1518 * shared catalogs can't have such updates.
1519 */
1520 relationId = indextup->indexrelid;
1521 databaseId = MyDatabaseId;
1522 }
1523 else if (tupleRelId == ConstraintRelationId)
1524 {
1525 Form_pg_constraint constrtup = (Form_pg_constraint) GETSTRUCT(tuple);
1526
1527 /*
1528 * Foreign keys are part of relcache entries, too, so send out an
1529 * inval for the table that the FK applies to.
1530 */
1531 if (constrtup->contype == CONSTRAINT_FOREIGN &&
1532 OidIsValid(constrtup->conrelid))
1533 {
1534 relationId = constrtup->conrelid;
1535 databaseId = MyDatabaseId;
1536 }
1537 else
1538 return;
1539 }
1540 else
1541 return;
1542
1543 /*
1544 * Yes. We need to register a relcache invalidation event.
1545 */
1546 RegisterRelcacheInvalidation(info, databaseId, relationId);
1547}
#define OidIsValid(objectId)
Definition: c.h:746
bool IsToastRelation(Relation relation)
Definition: catalog.c:175
bool IsCatalogRelation(Relation relation)
Definition: catalog.c:103
void PrepareToInvalidateCacheTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid, void *), void *context)
Definition: catcache.c:2354
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
static void RegisterRelcacheInvalidation(InvalidationInfo *info, Oid dbId, Oid relId)
Definition: inval.c:632
static void RegisterCatcacheInvalidation(int cacheId, uint32 hashValue, Oid dbId, void *context)
Definition: inval.c:604
static void RegisterSnapshotInvalidation(InvalidationInfo *info, Oid dbId, Oid relId)
Definition: inval.c:672
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:477
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
FormData_pg_class * Form_pg_class
Definition: pg_class.h:156
FormData_pg_constraint * Form_pg_constraint
FormData_pg_index * Form_pg_index
Definition: pg_index.h:70
#define RelationGetRelid(relation)
Definition: rel.h:516
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition: syscache.c:722

References GETSTRUCT(), InvalidOid, IsBootstrapProcessingMode, IsCatalogRelation(), IsSharedRelation(), IsToastRelation(), MyDatabaseId, OidIsValid, PrepareToInvalidateCacheTuple(), RegisterCatcacheInvalidation(), RegisterRelcacheInvalidation(), RegisterSnapshotInvalidation(), RelationGetRelid, and RelationInvalidatesSnapshotsOnly().

Referenced by CacheInvalidateHeapTuple(), and CacheInvalidateHeapTupleInplace().

◆ CacheInvalidateHeapTupleInplace()

void CacheInvalidateHeapTupleInplace ( Relation  relation,
HeapTuple  tuple,
HeapTuple  newtuple 
)

Definition at line 1578 of file inval.c.

1581{
1582 CacheInvalidateHeapTupleCommon(relation, tuple, newtuple,
1584}
static InvalidationInfo * PrepareInplaceInvalidationState(void)
Definition: inval.c:751

References CacheInvalidateHeapTupleCommon(), and PrepareInplaceInvalidationState().

Referenced by heap_inplace_lock().

◆ CacheInvalidateRelcache()

◆ CacheInvalidateRelcacheAll()

◆ CacheInvalidateRelcacheByRelid()

void CacheInvalidateRelcacheByRelid ( Oid  relid)

Definition at line 1677 of file inval.c.

1678{
1679 HeapTuple tup;
1680
1681 tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1682 if (!HeapTupleIsValid(tup))
1683 elog(ERROR, "cache lookup failed for relation %u", relid);
1685 ReleaseSysCache(tup);
1686}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
Definition: inval.c:1655
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221

References CacheInvalidateRelcacheByTuple(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), and SearchSysCache1().

Referenced by AlterConstrUpdateConstraintEntry(), ATExecAlterConstraintInternal(), ATExecAttachPartition(), DefineIndex(), DetachPartitionFinalize(), heap_drop_with_catalog(), InvalidatePublicationRels(), ReindexRelationConcurrently(), RemoveStatisticsById(), and StorePartitionBound().

◆ CacheInvalidateRelcacheByTuple()

void CacheInvalidateRelcacheByTuple ( HeapTuple  classTuple)

Definition at line 1655 of file inval.c.

1656{
1657 Form_pg_class classtup = (Form_pg_class) GETSTRUCT(classTuple);
1658 Oid databaseId;
1659 Oid relationId;
1660
1661 relationId = classtup->oid;
1662 if (classtup->relisshared)
1663 databaseId = InvalidOid;
1664 else
1665 databaseId = MyDatabaseId;
1667 databaseId, relationId);
1668}

References GETSTRUCT(), InvalidOid, MyDatabaseId, PrepareInvalidationState(), and RegisterRelcacheInvalidation().

Referenced by CacheInvalidateRelcacheByRelid(), copy_table_data(), CreateTriggerFiringOn(), index_update_stats(), RemoveRoleFromObjectPolicy(), SetRelationHasSubclass(), SetRelationRuleStatus(), and swap_relation_files().

◆ CacheInvalidateRelmap()

void CacheInvalidateRelmap ( Oid  databaseId)

Definition at line 1775 of file inval.c.

1776{
1778
1780 msg.rm.dbId = databaseId;
1781 /* check AddCatcacheInvalidationMessage() for an explanation */
1782 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1783
1785}
#define SHAREDINVALRELMAP_ID
Definition: sinval.h:97
SharedInvalRelmapMsg rm
Definition: sinval.h:131

References SharedInvalRelmapMsg::dbId, SharedInvalRelmapMsg::id, SharedInvalidationMessage::rm, SendSharedInvalidMessages(), SHAREDINVALRELMAP_ID, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by write_relmap_file().

◆ CacheInvalidateRelSync()

void CacheInvalidateRelSync ( Oid  relid)

Definition at line 1698 of file inval.c.

1699{
1701 MyDatabaseId, relid);
1702}
static void RegisterRelsyncInvalidation(InvalidationInfo *info, Oid dbId, Oid relId)
Definition: inval.c:660

References MyDatabaseId, PrepareInvalidationState(), and RegisterRelsyncInvalidation().

Referenced by CacheInvalidateRelSyncAll(), and InvalidatePubRelSyncCache().

◆ CacheInvalidateRelSyncAll()

void CacheInvalidateRelSyncAll ( void  )

Definition at line 1710 of file inval.c.

1711{
1713}
void CacheInvalidateRelSync(Oid relid)
Definition: inval.c:1698

References CacheInvalidateRelSync(), and InvalidOid.

Referenced by InvalidatePubRelSyncCache().

◆ CacheInvalidateSmgr()

void CacheInvalidateSmgr ( RelFileLocatorBackend  rlocator)

Definition at line 1741 of file inval.c.

1742{
1744
1745 /* verify optimization stated above stays valid */
1747 "MAX_BACKENDS_BITS is too big for inval.c");
1748
1749 msg.sm.id = SHAREDINVALSMGR_ID;
1750 msg.sm.backend_hi = rlocator.backend >> 16;
1751 msg.sm.backend_lo = rlocator.backend & 0xffff;
1752 msg.sm.rlocator = rlocator.locator;
1753 /* check AddCatcacheInvalidationMessage() for an explanation */
1754 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1755
1757}
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:909
#define MAX_BACKENDS_BITS
Definition: procnumber.h:38
#define SHAREDINVALSMGR_ID
Definition: sinval.h:86
RelFileLocator locator
uint16 backend_lo
Definition: sinval.h:93
RelFileLocator rlocator
Definition: sinval.h:94
SharedInvalSmgrMsg sm
Definition: sinval.h:130

References RelFileLocatorBackend::backend, SharedInvalSmgrMsg::backend_hi, SharedInvalSmgrMsg::backend_lo, SharedInvalSmgrMsg::id, RelFileLocatorBackend::locator, MAX_BACKENDS_BITS, SharedInvalSmgrMsg::rlocator, SendSharedInvalidMessages(), SHAREDINVALSMGR_ID, SharedInvalidationMessage::sm, StaticAssertStmt, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by smgrdounlinkall(), smgrtruncate(), and vm_extend().

◆ CacheRegisterRelcacheCallback()

void CacheRegisterRelcacheCallback ( RelcacheCallbackFunction  func,
Datum  arg 
)

Definition at line 1844 of file inval.c.

1846{
1848 elog(FATAL, "out of relcache_callback_list slots");
1849
1852
1854}
#define FATAL
Definition: elog.h:41
static int relcache_callback_count
Definition: inval.c:294
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
#define MAX_RELCACHE_CALLBACKS
Definition: inval.c:273
void * arg
RelcacheCallbackFunction function
Definition: inval.c:290

References RELCACHECALLBACK::arg, arg, elog, FATAL, RELCACHECALLBACK::function, MAX_RELCACHE_CALLBACKS, relcache_callback_count, and relcache_callback_list.

Referenced by init_rel_sync_cache(), InitializeRelfilenumberMap(), InitPlanCache(), logicalrep_partmap_init(), logicalrep_relmap_init(), and lookup_type_cache().

◆ CacheRegisterRelSyncCallback()

void CacheRegisterRelSyncCallback ( RelSyncCallbackFunction  func,
Datum  arg 
)

Definition at line 1865 of file inval.c.

1867{
1869 elog(FATAL, "out of relsync_callback_list slots");
1870
1873
1875}
static int relsync_callback_count
Definition: inval.c:302
static struct RELSYNCCALLBACK relsync_callback_list[MAX_RELSYNC_CALLBACKS]
#define MAX_RELSYNC_CALLBACKS
Definition: inval.c:274
RelSyncCallbackFunction function
Definition: inval.c:298
Datum arg
Definition: inval.c:299

References RELSYNCCALLBACK::arg, arg, elog, FATAL, RELSYNCCALLBACK::function, MAX_RELSYNC_CALLBACKS, relsync_callback_count, and relsync_callback_list.

Referenced by pgoutput_startup().

◆ CacheRegisterSyscacheCallback()

void CacheRegisterSyscacheCallback ( int  cacheid,
SyscacheCallbackFunction  func,
Datum  arg 
)

Definition at line 1802 of file inval.c.

1805{
1806 if (cacheid < 0 || cacheid >= SysCacheSize)
1807 elog(FATAL, "invalid cache ID: %d", cacheid);
1809 elog(FATAL, "out of syscache_callback_list slots");
1810
1811 if (syscache_callback_links[cacheid] == 0)
1812 {
1813 /* first callback for this cache */
1815 }
1816 else
1817 {
1818 /* add to end of chain, so that older callbacks are called first */
1819 int i = syscache_callback_links[cacheid] - 1;
1820
1821 while (syscache_callback_list[i].link > 0)
1824 }
1825
1830
1832}
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
#define MAX_SYSCACHE_CALLBACKS
Definition: inval.c:272
static int16 syscache_callback_links[SysCacheSize]
Definition: inval.c:284
static int syscache_callback_count
Definition: inval.c:286
int i
Definition: isn.c:77
SyscacheCallbackFunction function
Definition: inval.c:280
int16 link
Definition: inval.c:279

References SYSCACHECALLBACK::arg, arg, elog, FATAL, SYSCACHECALLBACK::function, i, SYSCACHECALLBACK::id, SYSCACHECALLBACK::link, MAX_SYSCACHE_CALLBACKS, syscache_callback_count, syscache_callback_links, and syscache_callback_list.

Referenced by BuildEventTriggerCache(), find_oper_cache_entry(), GetConnection(), init_rel_sync_cache(), init_ts_config_cache(), initialize_acl(), InitializeAttoptCache(), InitializeLogRepWorker(), InitializeSearchPath(), InitializeShippableCache(), InitializeTableSpaceCache(), InitPlanCache(), lookup_proof_cache(), lookup_ts_dictionary_cache(), lookup_ts_parser_cache(), lookup_type_cache(), ParallelApplyWorkerMain(), pgoutput_startup(), ri_InitHashTables(), SetupApplyOrSyncWorker(), and superuser_arg().

◆ CallRelSyncCallbacks()

void CallRelSyncCallbacks ( Oid  relid)

Definition at line 1906 of file inval.c.

1907{
1908 for (int i = 0; i < relsync_callback_count; i++)
1909 {
1910 struct RELSYNCCALLBACK *ccitem = relsync_callback_list + i;
1911
1912 ccitem->function(ccitem->arg, relid);
1913 }
1914}

References RELSYNCCALLBACK::arg, RELSYNCCALLBACK::function, i, relsync_callback_count, and relsync_callback_list.

Referenced by LocalExecuteInvalidationMessage().

◆ CallSyscacheCallbacks()

void CallSyscacheCallbacks ( int  cacheid,
uint32  hashvalue 
)

Definition at line 1884 of file inval.c.

1885{
1886 int i;
1887
1888 if (cacheid < 0 || cacheid >= SysCacheSize)
1889 elog(ERROR, "invalid cache ID: %d", cacheid);
1890
1891 i = syscache_callback_links[cacheid] - 1;
1892 while (i >= 0)
1893 {
1894 struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
1895
1896 Assert(ccitem->id == cacheid);
1897 ccitem->function(ccitem->arg, cacheid, hashvalue);
1898 i = ccitem->link - 1;
1899 }
1900}

References SYSCACHECALLBACK::arg, Assert(), elog, ERROR, SYSCACHECALLBACK::function, i, SYSCACHECALLBACK::id, SYSCACHECALLBACK::link, syscache_callback_links, and syscache_callback_list.

Referenced by CatalogCacheFlushCatalog(), and LocalExecuteInvalidationMessage().

◆ CommandEndInvalidationMessages()

void CommandEndInvalidationMessages ( void  )

Definition at line 1402 of file inval.c.

1403{
1404 /*
1405 * You might think this shouldn't be called outside any transaction, but
1406 * bootstrap does it, and also ABORT issued when not in a transaction. So
1407 * just quietly return if no state to work on.
1408 */
1409 if (transInvalInfo == NULL)
1410 return;
1411
1414
1415 /* WAL Log per-command invalidation messages for wal_level=logical */
1418
1421}
void LogLogicalInvalidations(void)
Definition: inval.c:1925
#define XLogLogicalInfoActive()
Definition: xlog.h:126

References AppendInvalidationMessages(), InvalidationInfo::CurrentCmdInvalidMsgs, TransInvalidationInfo::ii, LocalExecuteInvalidationMessage(), LogLogicalInvalidations(), TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessInvalidationMessages(), transInvalInfo, and XLogLogicalInfoActive.

Referenced by AtCCI_LocalCache(), and AtEOSubXact_Inval().

◆ ForgetInplace_Inval()

void ForgetInplace_Inval ( void  )

Definition at line 1279 of file inval.c.

1280{
1281 inplaceInvalInfo = NULL;
1282}

References inplaceInvalInfo.

Referenced by heap_inplace_lock(), and heap_inplace_unlock().

◆ inplaceGetInvalidationMessages()

int inplaceGetInvalidationMessages ( SharedInvalidationMessage **  msgs,
bool *  RelcacheInitFileInval 
)

Definition at line 1081 of file inval.c.

1083{
1084 SharedInvalidationMessage *msgarray;
1085 int nummsgs;
1086 int nmsgs;
1087
1088 /* Quick exit if we haven't done anything with invalidation messages. */
1089 if (inplaceInvalInfo == NULL)
1090 {
1091 *RelcacheInitFileInval = false;
1092 *msgs = NULL;
1093 return 0;
1094 }
1095
1096 *RelcacheInitFileInval = inplaceInvalInfo->RelcacheInitFileInval;
1098 *msgs = msgarray = (SharedInvalidationMessage *)
1099 palloc(nummsgs * sizeof(SharedInvalidationMessage));
1100
1101 nmsgs = 0;
1104 (memcpy(msgarray + nmsgs,
1105 msgs,
1106 n * sizeof(SharedInvalidationMessage)),
1107 nmsgs += n));
1110 (memcpy(msgarray + nmsgs,
1111 msgs,
1112 n * sizeof(SharedInvalidationMessage)),
1113 nmsgs += n));
1114 Assert(nmsgs == nummsgs);
1115
1116 return nmsgs;
1117}
#define NumMessagesInGroup(group)
Definition: inval.c:207
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
Definition: inval.c:402
void * palloc(Size size)
Definition: mcxt.c:1940

References Assert(), CatCacheMsgs, InvalidationInfo::CurrentCmdInvalidMsgs, inplaceInvalInfo, NumMessagesInGroup, palloc(), ProcessMessageSubGroupMulti, InvalidationInfo::RelcacheInitFileInval, and RelCacheMsgs.

Referenced by heap_inplace_update_and_unlock().

◆ InvalidateSystemCaches()

◆ InvalidateSystemCachesExtended()

void InvalidateSystemCachesExtended ( bool  debug_discard)

Definition at line 784 of file inval.c.

785{
786 int i;
787
789 ResetCatalogCachesExt(debug_discard);
790 RelationCacheInvalidate(debug_discard); /* gets smgr and relmap too */
791
792 for (i = 0; i < syscache_callback_count; i++)
793 {
794 struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
795
796 ccitem->function(ccitem->arg, ccitem->id, 0);
797 }
798
799 for (i = 0; i < relcache_callback_count; i++)
800 {
801 struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
802
803 ccitem->function(ccitem->arg, InvalidOid);
804 }
805
806 for (i = 0; i < relsync_callback_count; i++)
807 {
808 struct RELSYNCCALLBACK *ccitem = relsync_callback_list + i;
809
810 ccitem->function(ccitem->arg, InvalidOid);
811 }
812}
void ResetCatalogCachesExt(bool debug_discard)
Definition: catcache.c:804
void RelationCacheInvalidate(bool debug_discard)
Definition: relcache.c:2980
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:443

References SYSCACHECALLBACK::arg, RELCACHECALLBACK::arg, RELSYNCCALLBACK::arg, SYSCACHECALLBACK::function, RELCACHECALLBACK::function, RELSYNCCALLBACK::function, i, SYSCACHECALLBACK::id, InvalidateCatalogSnapshot(), InvalidOid, RelationCacheInvalidate(), relcache_callback_count, relcache_callback_list, relsync_callback_count, relsync_callback_list, ResetCatalogCachesExt(), syscache_callback_count, and syscache_callback_list.

Referenced by AcceptInvalidationMessages(), and InvalidateSystemCaches().

◆ LocalExecuteInvalidationMessage()

void LocalExecuteInvalidationMessage ( SharedInvalidationMessage msg)

Definition at line 822 of file inval.c.

823{
824 if (msg->id >= 0)
825 {
826 if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid)
827 {
829
830 SysCacheInvalidate(msg->cc.id, msg->cc.hashValue);
831
833 }
834 }
835 else if (msg->id == SHAREDINVALCATALOG_ID)
836 {
837 if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid)
838 {
840
842
843 /* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */
844 }
845 }
846 else if (msg->id == SHAREDINVALRELCACHE_ID)
847 {
848 if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid)
849 {
850 int i;
851
852 if (msg->rc.relId == InvalidOid)
854 else
856
857 for (i = 0; i < relcache_callback_count; i++)
858 {
859 struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
860
861 ccitem->function(ccitem->arg, msg->rc.relId);
862 }
863 }
864 }
865 else if (msg->id == SHAREDINVALSMGR_ID)
866 {
867 /*
868 * We could have smgr entries for relations of other databases, so no
869 * short-circuit test is possible here.
870 */
871 RelFileLocatorBackend rlocator;
872
873 rlocator.locator = msg->sm.rlocator;
874 rlocator.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo;
875 smgrreleaserellocator(rlocator);
876 }
877 else if (msg->id == SHAREDINVALRELMAP_ID)
878 {
879 /* We only care about our own database and shared catalogs */
880 if (msg->rm.dbId == InvalidOid)
882 else if (msg->rm.dbId == MyDatabaseId)
884 }
885 else if (msg->id == SHAREDINVALSNAPSHOT_ID)
886 {
887 /* We only care about our own database and shared catalogs */
888 if (msg->sn.dbId == InvalidOid)
890 else if (msg->sn.dbId == MyDatabaseId)
892 }
893 else if (msg->id == SHAREDINVALRELSYNC_ID)
894 {
895 /* We only care about our own database */
896 if (msg->rs.dbId == MyDatabaseId)
898 }
899 else
900 elog(FATAL, "unrecognized SI message ID: %d", msg->id);
901}
void CatalogCacheFlushCatalog(Oid catId)
Definition: catcache.c:834
void CallRelSyncCallbacks(Oid relid)
Definition: inval.c:1906
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1884
void RelationCacheInvalidateEntry(Oid relationId)
Definition: relcache.c:2924
void RelationMapInvalidate(bool shared)
Definition: relmapper.c:468
void smgrreleaserellocator(RelFileLocatorBackend rlocator)
Definition: smgr.c:443
void SysCacheInvalidate(int cacheId, uint32 hashValue)
Definition: syscache.c:698
SharedInvalRelSyncMsg rs
Definition: sinval.h:133

References RELCACHECALLBACK::arg, RelFileLocatorBackend::backend, SharedInvalSmgrMsg::backend_hi, SharedInvalSmgrMsg::backend_lo, CallRelSyncCallbacks(), CallSyscacheCallbacks(), SharedInvalidationMessage::cat, CatalogCacheFlushCatalog(), SharedInvalCatalogMsg::catId, SharedInvalidationMessage::cc, SharedInvalCatcacheMsg::dbId, SharedInvalCatalogMsg::dbId, SharedInvalRelcacheMsg::dbId, SharedInvalRelmapMsg::dbId, SharedInvalSnapshotMsg::dbId, SharedInvalRelSyncMsg::dbId, elog, FATAL, RELCACHECALLBACK::function, SharedInvalCatcacheMsg::hashValue, i, SharedInvalCatcacheMsg::id, SharedInvalidationMessage::id, InvalidateCatalogSnapshot(), InvalidOid, RelFileLocatorBackend::locator, MyDatabaseId, SharedInvalidationMessage::rc, RelationCacheInvalidate(), RelationCacheInvalidateEntry(), RelationMapInvalidate(), relcache_callback_count, relcache_callback_list, SharedInvalRelcacheMsg::relId, SharedInvalRelSyncMsg::relid, SharedInvalSmgrMsg::rlocator, SharedInvalidationMessage::rm, SharedInvalidationMessage::rs, SHAREDINVALCATALOG_ID, SHAREDINVALRELCACHE_ID, SHAREDINVALRELMAP_ID, SHAREDINVALRELSYNC_ID, SHAREDINVALSMGR_ID, SHAREDINVALSNAPSHOT_ID, SharedInvalidationMessage::sm, smgrreleaserellocator(), SharedInvalidationMessage::sn, and SysCacheInvalidate().

Referenced by AcceptInvalidationMessages(), AtEOSubXact_Inval(), AtEOXact_Inval(), CommandEndInvalidationMessages(), ReorderBufferExecuteInvalidations(), and ReorderBufferImmediateInvalidation().

◆ LogLogicalInvalidations()

void LogLogicalInvalidations ( void  )

Definition at line 1925 of file inval.c.

1926{
1927 xl_xact_invals xlrec;
1928 InvalidationMsgsGroup *group;
1929 int nmsgs;
1930
1931 /* Quick exit if we haven't done anything with invalidation messages. */
1932 if (transInvalInfo == NULL)
1933 return;
1934
1936 nmsgs = NumMessagesInGroup(group);
1937
1938 if (nmsgs > 0)
1939 {
1940 /* prepare record */
1941 memset(&xlrec, 0, MinSizeOfXactInvals);
1942 xlrec.nmsgs = nmsgs;
1943
1944 /* perform insertion */
1948 XLogRegisterData(msgs,
1949 n * sizeof(SharedInvalidationMessage)));
1951 XLogRegisterData(msgs,
1952 n * sizeof(SharedInvalidationMessage)));
1954 }
1955}
int nmsgs
Definition: xact.h:304
#define MinSizeOfXactInvals
Definition: xact.h:307
#define XLOG_XACT_INVALIDATIONS
Definition: xact.h:175
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogRegisterData(const void *data, uint32 len)
Definition: xloginsert.c:364
void XLogBeginInsert(void)
Definition: xloginsert.c:149

References CatCacheMsgs, InvalidationInfo::CurrentCmdInvalidMsgs, TransInvalidationInfo::ii, MinSizeOfXactInvals, xl_xact_invals::nmsgs, NumMessagesInGroup, ProcessMessageSubGroupMulti, RelCacheMsgs, transInvalInfo, XLOG_XACT_INVALIDATIONS, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by CommandEndInvalidationMessages(), and RecordTransactionCommit().

◆ PostPrepare_Inval()

void PostPrepare_Inval ( void  )

Definition at line 986 of file inval.c.

987{
988 AtEOXact_Inval(false);
989}
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1192

References AtEOXact_Inval().

Referenced by PrepareTransaction().

◆ PreInplace_Inval()

◆ PrepareInplaceInvalidationState()

static InvalidationInfo * PrepareInplaceInvalidationState ( void  )
static

Definition at line 751 of file inval.c.

752{
753 InvalidationInfo *myInfo;
754
756 /* limit of one inplace update under assembly */
757 Assert(inplaceInvalInfo == NULL);
758
759 /* gone after WAL insertion CritSection ends, so use current context */
760 myInfo = (InvalidationInfo *) palloc0(sizeof(InvalidationInfo));
761
762 /* Stash our messages past end of the transactional messages, if any. */
763 if (transInvalInfo != NULL)
766 else
767 {
772 }
773
774 inplaceInvalInfo = myInfo;
775 return myInfo;
776}
void * palloc0(Size size)
Definition: mcxt.c:1970
bool IsTransactionState(void)
Definition: xact.c:387

References Assert(), CatCacheMsgs, InvalidationInfo::CurrentCmdInvalidMsgs, TransInvalidationInfo::ii, inplaceInvalInfo, InvalMessageArrays, IsTransactionState(), InvalMessageArray::maxmsgs, InvalMessageArray::msgs, palloc0(), RelCacheMsgs, SetGroupToFollow, and transInvalInfo.

Referenced by CacheInvalidateHeapTupleInplace().

◆ PrepareInvalidationState()

static InvalidationInfo * PrepareInvalidationState ( void  )
static

Definition at line 682 of file inval.c.

683{
684 TransInvalidationInfo *myInfo;
685
687 /* Can't queue transactional message while collecting inplace messages. */
688 Assert(inplaceInvalInfo == NULL);
689
690 if (transInvalInfo != NULL &&
693
694 myInfo = (TransInvalidationInfo *)
696 sizeof(TransInvalidationInfo));
697 myInfo->parent = transInvalInfo;
699
700 /* Now, do we have a previous stack entry? */
701 if (transInvalInfo != NULL)
702 {
703 /* Yes; this one should be for a deeper nesting level. */
705
706 /*
707 * The parent (sub)transaction must not have any current (i.e.,
708 * not-yet-locally-processed) messages. If it did, we'd have a
709 * semantic problem: the new subtransaction presumably ought not be
710 * able to see those events yet, but since the CommandCounter is
711 * linear, that can't work once the subtransaction advances the
712 * counter. This is a convenient place to check for that, as well as
713 * being important to keep management of the message arrays simple.
714 */
716 elog(ERROR, "cannot start a subtransaction when there are unprocessed inval messages");
717
718 /*
719 * MemoryContextAllocZero set firstmsg = nextmsg = 0 in each group,
720 * which is fine for the first (sub)transaction, but otherwise we need
721 * to update them to follow whatever is already in the arrays.
722 */
726 &myInfo->PriorCmdInvalidMsgs);
727 }
728 else
729 {
730 /*
731 * Here, we need only clear any array pointers left over from a prior
732 * transaction.
733 */
738 }
739
740 transInvalInfo = myInfo;
741 return (InvalidationInfo *) myInfo;
742}
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1290

References Assert(), CatCacheMsgs, InvalidationInfo::CurrentCmdInvalidMsgs, elog, ERROR, GetCurrentTransactionNestLevel(), TransInvalidationInfo::ii, inplaceInvalInfo, InvalMessageArrays, IsTransactionState(), InvalMessageArray::maxmsgs, MemoryContextAllocZero(), InvalMessageArray::msgs, TransInvalidationInfo::my_level, NumMessagesInGroup, TransInvalidationInfo::parent, TransInvalidationInfo::PriorCmdInvalidMsgs, RelCacheMsgs, SetGroupToFollow, TopTransactionContext, and transInvalInfo.

Referenced by CacheInvalidateCatalog(), CacheInvalidateHeapTuple(), CacheInvalidateRelcache(), CacheInvalidateRelcacheAll(), CacheInvalidateRelcacheByTuple(), and CacheInvalidateRelSync().

◆ ProcessCommittedInvalidationMessages()

void ProcessCommittedInvalidationMessages ( SharedInvalidationMessage msgs,
int  nmsgs,
bool  RelcacheInitFileInval,
Oid  dbid,
Oid  tsid 
)

Definition at line 1128 of file inval.c.

1131{
1132 if (nmsgs <= 0)
1133 return;
1134
1135 elog(DEBUG4, "replaying commit with %d messages%s", nmsgs,
1136 (RelcacheInitFileInval ? " and relcache file invalidation" : ""));
1137
1138 if (RelcacheInitFileInval)
1139 {
1140 elog(DEBUG4, "removing relcache init files for database %u", dbid);
1141
1142 /*
1143 * RelationCacheInitFilePreInvalidate, when the invalidation message
1144 * is for a specific database, requires DatabasePath to be set, but we
1145 * should not use SetDatabasePath during recovery, since it is
1146 * intended to be used only once by normal backends. Hence, a quick
1147 * hack: set DatabasePath directly then unset after use.
1148 */
1149 if (OidIsValid(dbid))
1150 DatabasePath = GetDatabasePath(dbid, tsid);
1151
1153
1154 if (OidIsValid(dbid))
1155 {
1157 DatabasePath = NULL;
1158 }
1159 }
1160
1161 SendSharedInvalidMessages(msgs, nmsgs);
1162
1163 if (RelcacheInitFileInval)
1165}
#define DEBUG4
Definition: elog.h:27
char * DatabasePath
Definition: globals.c:105
char * GetDatabasePath(Oid dbOid, Oid spcOid)
Definition: relpath.c:110

References DatabasePath, DEBUG4, elog, GetDatabasePath(), OidIsValid, pfree(), RelationCacheInitFilePostInvalidate(), RelationCacheInitFilePreInvalidate(), and SendSharedInvalidMessages().

Referenced by heap_xlog_inplace(), standby_redo(), and xact_redo_commit().

◆ ProcessInvalidationMessages()

static void ProcessInvalidationMessages ( InvalidationMsgsGroup group,
void(*)(SharedInvalidationMessage *msg)  func 
)
static

Definition at line 574 of file inval.c.

576{
577 ProcessMessageSubGroup(group, CatCacheMsgs, func(msg));
578 ProcessMessageSubGroup(group, RelCacheMsgs, func(msg));
579}

References CatCacheMsgs, ProcessMessageSubGroup, and RelCacheMsgs.

Referenced by AtEOSubXact_Inval(), AtEOXact_Inval(), and CommandEndInvalidationMessages().

◆ ProcessInvalidationMessagesMulti()

static void ProcessInvalidationMessagesMulti ( InvalidationMsgsGroup group,
void(*)(const SharedInvalidationMessage *msgs, int n)  func 
)
static

Definition at line 586 of file inval.c.

588{
589 ProcessMessageSubGroupMulti(group, CatCacheMsgs, func(msgs, n));
590 ProcessMessageSubGroupMulti(group, RelCacheMsgs, func(msgs, n));
591}

References CatCacheMsgs, ProcessMessageSubGroupMulti, and RelCacheMsgs.

Referenced by AtEOXact_Inval(), and AtInplace_Inval().

◆ RegisterCatalogInvalidation()

static void RegisterCatalogInvalidation ( InvalidationInfo info,
Oid  dbId,
Oid  catId 
)
static

Definition at line 621 of file inval.c.

622{
624}
static void AddCatalogInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid catId)
Definition: inval.c:453

References AddCatalogInvalidationMessage(), and InvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateCatalog().

◆ RegisterCatcacheInvalidation()

static void RegisterCatcacheInvalidation ( int  cacheId,
uint32  hashValue,
Oid  dbId,
void *  context 
)
static

Definition at line 604 of file inval.c.

608{
609 InvalidationInfo *info = (InvalidationInfo *) context;
610
612 cacheId, hashValue, dbId);
613}
static void AddCatcacheInvalidationMessage(InvalidationMsgsGroup *group, int id, uint32 hashValue, Oid dbId)
Definition: inval.c:425

References AddCatcacheInvalidationMessage(), and InvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateHeapTupleCommon().

◆ RegisterRelcacheInvalidation()

static void RegisterRelcacheInvalidation ( InvalidationInfo info,
Oid  dbId,
Oid  relId 
)
static

Definition at line 632 of file inval.c.

633{
635
636 /*
637 * Most of the time, relcache invalidation is associated with system
638 * catalog updates, but there are a few cases where it isn't. Quick hack
639 * to ensure that the next CommandCounterIncrement() will think that we
640 * need to do CommandEndInvalidationMessages().
641 */
642 (void) GetCurrentCommandId(true);
643
644 /*
645 * If the relation being invalidated is one of those cached in a relcache
646 * init file, mark that we need to zap that file at commit. For simplicity
647 * invalidations for a specific database always invalidate the shared file
648 * as well. Also zap when we are invalidating whole relcache.
649 */
650 if (relId == InvalidOid || RelationIdIsInInitFile(relId))
651 info->RelcacheInitFileInval = true;
652}
static void AddRelcacheInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid relId)
Definition: inval.c:471
bool RelationIdIsInInitFile(Oid relationId)
Definition: relcache.c:6803
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:829

References AddRelcacheInvalidationMessage(), InvalidationInfo::CurrentCmdInvalidMsgs, GetCurrentCommandId(), InvalidOid, RelationIdIsInInitFile(), and InvalidationInfo::RelcacheInitFileInval.

Referenced by CacheInvalidateHeapTupleCommon(), CacheInvalidateRelcache(), CacheInvalidateRelcacheAll(), and CacheInvalidateRelcacheByTuple().

◆ RegisterRelsyncInvalidation()

static void RegisterRelsyncInvalidation ( InvalidationInfo info,
Oid  dbId,
Oid  relId 
)
static

Definition at line 660 of file inval.c.

661{
663}
static void AddRelsyncInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid relId)
Definition: inval.c:505

References AddRelsyncInvalidationMessage(), and InvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateRelSync().

◆ RegisterSnapshotInvalidation()

static void RegisterSnapshotInvalidation ( InvalidationInfo info,
Oid  dbId,
Oid  relId 
)
static

Definition at line 672 of file inval.c.

673{
675}
static void AddSnapshotInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid relId)
Definition: inval.c:533

References AddSnapshotInvalidationMessage(), and InvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateHeapTupleCommon().

◆ xactGetCommittedInvalidationMessages()

int xactGetCommittedInvalidationMessages ( SharedInvalidationMessage **  msgs,
bool *  RelcacheInitFileInval 
)

Definition at line 1005 of file inval.c.

1007{
1008 SharedInvalidationMessage *msgarray;
1009 int nummsgs;
1010 int nmsgs;
1011
1012 /* Quick exit if we haven't done anything with invalidation messages. */
1013 if (transInvalInfo == NULL)
1014 {
1015 *RelcacheInitFileInval = false;
1016 *msgs = NULL;
1017 return 0;
1018 }
1019
1020 /* Must be at top of stack */
1022
1023 /*
1024 * Relcache init file invalidation requires processing both before and
1025 * after we send the SI messages. However, we need not do anything unless
1026 * we committed.
1027 */
1028 *RelcacheInitFileInval = transInvalInfo->ii.RelcacheInitFileInval;
1029
1030 /*
1031 * Collect all the pending messages into a single contiguous array of
1032 * invalidation messages, to simplify what needs to happen while building
1033 * the commit WAL message. Maintain the order that they would be
1034 * processed in by AtEOXact_Inval(), to ensure emulated behaviour in redo
1035 * is as similar as possible to original. We want the same bugs, if any,
1036 * not new ones.
1037 */
1040
1041 *msgs = msgarray = (SharedInvalidationMessage *)
1043 nummsgs * sizeof(SharedInvalidationMessage));
1044
1045 nmsgs = 0;
1048 (memcpy(msgarray + nmsgs,
1049 msgs,
1050 n * sizeof(SharedInvalidationMessage)),
1051 nmsgs += n));
1054 (memcpy(msgarray + nmsgs,
1055 msgs,
1056 n * sizeof(SharedInvalidationMessage)),
1057 nmsgs += n));
1060 (memcpy(msgarray + nmsgs,
1061 msgs,
1062 n * sizeof(SharedInvalidationMessage)),
1063 nmsgs += n));
1066 (memcpy(msgarray + nmsgs,
1067 msgs,
1068 n * sizeof(SharedInvalidationMessage)),
1069 nmsgs += n));
1070 Assert(nmsgs == nummsgs);
1071
1072 return nmsgs;
1073}
MemoryContext CurTransactionContext
Definition: mcxt.c:171

References Assert(), CatCacheMsgs, InvalidationInfo::CurrentCmdInvalidMsgs, CurTransactionContext, TransInvalidationInfo::ii, MemoryContextAlloc(), TransInvalidationInfo::my_level, NumMessagesInGroup, TransInvalidationInfo::parent, TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessMessageSubGroupMulti, InvalidationInfo::RelcacheInitFileInval, RelCacheMsgs, and transInvalInfo.

Referenced by RecordTransactionCommit(), and StartPrepare().

Variable Documentation

◆ debug_discard_caches

int debug_discard_caches = 0

Definition at line 260 of file inval.c.

Referenced by AcceptInvalidationMessages(), LookupOpclassInfo(), and RelationBuildDesc().

◆ inplaceInvalInfo

◆ InvalMessageArrays

InvalMessageArray InvalMessageArrays[2]
static

◆ relcache_callback_count

int relcache_callback_count = 0
static

◆ relcache_callback_list

◆ relsync_callback_count

int relsync_callback_count = 0
static

◆ relsync_callback_list

◆ syscache_callback_count

int syscache_callback_count = 0
static

Definition at line 286 of file inval.c.

Referenced by CacheRegisterSyscacheCallback(), and InvalidateSystemCachesExtended().

◆ syscache_callback_links

int16 syscache_callback_links[SysCacheSize]
static

Definition at line 284 of file inval.c.

Referenced by CacheRegisterSyscacheCallback(), and CallSyscacheCallbacks().

◆ syscache_callback_list

◆ transInvalInfo