PostgreSQL Source Code git master
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 930 of file inval.c.

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

References AssertCouldGetRelation(), debug_discard_caches, InvalidateSystemCaches(), InvalidateSystemCachesExtended(), IsTransactionState(), 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:1260
MemoryContext TopTransactionContext
Definition: mcxt.c:170
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:2172

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 1310 of file inval.c.

1311{
1312 int my_level;
1313 TransInvalidationInfo *myInfo;
1314
1315 /*
1316 * Successful inplace update must clear this, but we clear it on abort.
1317 * Inplace updates allocate this in CurrentMemoryContext, which has
1318 * lifespan <= subtransaction lifespan. Hence, don't free it explicitly.
1319 */
1320 if (isCommit)
1321 Assert(inplaceInvalInfo == NULL);
1322 else
1323 inplaceInvalInfo = NULL;
1324
1325 /* Quick exit if no transactional messages. */
1326 myInfo = transInvalInfo;
1327 if (myInfo == NULL)
1328 return;
1329
1330 /* Also bail out quickly if messages are not for this level. */
1331 my_level = GetCurrentTransactionNestLevel();
1332 if (myInfo->my_level != my_level)
1333 {
1334 Assert(myInfo->my_level < my_level);
1335 return;
1336 }
1337
1338 if (isCommit)
1339 {
1340 /* If CurrentCmdInvalidMsgs still has anything, fix it */
1342
1343 /*
1344 * We create invalidation stack entries lazily, so the parent might
1345 * not have one. Instead of creating one, moving all the data over,
1346 * and then freeing our own, we can just adjust the level of our own
1347 * entry.
1348 */
1349 if (myInfo->parent == NULL || myInfo->parent->my_level < my_level - 1)
1350 {
1351 myInfo->my_level--;
1352 return;
1353 }
1354
1355 /*
1356 * Pass up my inval messages to parent. Notice that we stick them in
1357 * PriorCmdInvalidMsgs, not CurrentCmdInvalidMsgs, since they've
1358 * already been locally processed. (This would trigger the Assert in
1359 * AppendInvalidationMessageSubGroup if the parent's
1360 * CurrentCmdInvalidMsgs isn't empty; but we already checked that in
1361 * PrepareInvalidationState.)
1362 */
1364 &myInfo->PriorCmdInvalidMsgs);
1365
1366 /* Must readjust parent's CurrentCmdInvalidMsgs indexes now */
1368 &myInfo->parent->PriorCmdInvalidMsgs);
1369
1370 /* Pending relcache inval becomes parent's problem too */
1371 if (myInfo->ii.RelcacheInitFileInval)
1372 myInfo->parent->ii.RelcacheInitFileInval = true;
1373
1374 /* Pop the transaction state stack */
1375 transInvalInfo = myInfo->parent;
1376
1377 /* Need not free anything else explicitly */
1378 pfree(myInfo);
1379 }
1380 else
1381 {
1384
1385 /* Pop the transaction state stack */
1386 transInvalInfo = myInfo->parent;
1387
1388 /* Need not free anything else explicitly */
1389 pfree(myInfo);
1390 }
1391}
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:1409
void pfree(void *pointer)
Definition: mcxt.c:2152
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 1199 of file inval.c.

1200{
1201 inplaceInvalInfo = NULL;
1202
1203 /* Quick exit if no transactional messages */
1204 if (transInvalInfo == NULL)
1205 return;
1206
1207 /* Must be at top of stack */
1209
1210 INJECTION_POINT("transaction-end-process-inval");
1211
1212 if (isCommit)
1213 {
1214 /*
1215 * Relcache init file invalidation requires processing both before and
1216 * after we send the SI messages. However, we need not do anything
1217 * unless we committed.
1218 */
1221
1224
1227
1230 }
1231 else
1232 {
1235 }
1236
1237 /* Need not free anything explicitly */
1238 transInvalInfo = NULL;
1239}
#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:6882
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6857
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 1608 of file inval.c.

1609{
1610 Oid databaseId;
1611
1612 if (IsSharedRelation(catalogId))
1613 databaseId = InvalidOid;
1614 else
1615 databaseId = MyDatabaseId;
1616
1618 databaseId, catalogId);
1619}
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:304
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 1571 of file inval.c.

1574{
1575 CacheInvalidateHeapTupleCommon(relation, tuple, newtuple,
1577}
static void CacheInvalidateHeapTupleCommon(Relation relation, HeapTuple tuple, HeapTuple newtuple, InvalidationInfo *(*prepare_callback)(void))
Definition: inval.c:1436

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 1436 of file inval.c.

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

1591{
1592 CacheInvalidateHeapTupleCommon(relation, tuple, newtuple,
1594}
static InvalidationInfo * PrepareInplaceInvalidationState(void)
Definition: inval.c:752

References CacheInvalidateHeapTupleCommon(), and PrepareInplaceInvalidationState().

Referenced by heap_inplace_lock().

◆ CacheInvalidateRelcache()

◆ CacheInvalidateRelcacheAll()

◆ CacheInvalidateRelcacheByRelid()

void CacheInvalidateRelcacheByRelid ( Oid  relid)

Definition at line 1687 of file inval.c.

1688{
1689 HeapTuple tup;
1690
1691 tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1692 if (!HeapTupleIsValid(tup))
1693 elog(ERROR, "cache lookup failed for relation %u", relid);
1695 ReleaseSysCache(tup);
1696}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
Definition: inval.c:1665
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 1665 of file inval.c.

1666{
1667 Form_pg_class classtup = (Form_pg_class) GETSTRUCT(classTuple);
1668 Oid databaseId;
1669 Oid relationId;
1670
1671 relationId = classtup->oid;
1672 if (classtup->relisshared)
1673 databaseId = InvalidOid;
1674 else
1675 databaseId = MyDatabaseId;
1677 databaseId, relationId);
1678}

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 1785 of file inval.c.

1786{
1788
1790 msg.rm.dbId = databaseId;
1791 /* check AddCatcacheInvalidationMessage() for an explanation */
1792 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1793
1795}
#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 1708 of file inval.c.

1709{
1711 MyDatabaseId, relid);
1712}
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 1720 of file inval.c.

1721{
1723}
void CacheInvalidateRelSync(Oid relid)
Definition: inval.c:1708

References CacheInvalidateRelSync(), and InvalidOid.

Referenced by InvalidatePubRelSyncCache().

◆ CacheInvalidateSmgr()

void CacheInvalidateSmgr ( RelFileLocatorBackend  rlocator)

Definition at line 1751 of file inval.c.

1752{
1754
1755 /* verify optimization stated above stays valid */
1757 "MAX_BACKENDS_BITS is too big for inval.c");
1758
1759 msg.sm.id = SHAREDINVALSMGR_ID;
1760 msg.sm.backend_hi = rlocator.backend >> 16;
1761 msg.sm.backend_lo = rlocator.backend & 0xffff;
1762 msg.sm.rlocator = rlocator.locator;
1763 /* check AddCatcacheInvalidationMessage() for an explanation */
1764 VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1765
1767}
#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 1854 of file inval.c.

1856{
1858 elog(FATAL, "out of relcache_callback_list slots");
1859
1862
1864}
#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 1875 of file inval.c.

1877{
1879 elog(FATAL, "out of relsync_callback_list slots");
1880
1883
1885}
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 1812 of file inval.c.

1815{
1816 if (cacheid < 0 || cacheid >= SysCacheSize)
1817 elog(FATAL, "invalid cache ID: %d", cacheid);
1819 elog(FATAL, "out of syscache_callback_list slots");
1820
1821 if (syscache_callback_links[cacheid] == 0)
1822 {
1823 /* first callback for this cache */
1825 }
1826 else
1827 {
1828 /* add to end of chain, so that older callbacks are called first */
1829 int i = syscache_callback_links[cacheid] - 1;
1830
1831 while (syscache_callback_list[i].link > 0)
1834 }
1835
1840
1842}
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 1916 of file inval.c.

1917{
1918 for (int i = 0; i < relsync_callback_count; i++)
1919 {
1920 struct RELSYNCCALLBACK *ccitem = relsync_callback_list + i;
1921
1922 ccitem->function(ccitem->arg, relid);
1923 }
1924}

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 1894 of file inval.c.

1895{
1896 int i;
1897
1898 if (cacheid < 0 || cacheid >= SysCacheSize)
1899 elog(ERROR, "invalid cache ID: %d", cacheid);
1900
1901 i = syscache_callback_links[cacheid] - 1;
1902 while (i >= 0)
1903 {
1904 struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
1905
1906 Assert(ccitem->id == cacheid);
1907 ccitem->function(ccitem->arg, cacheid, hashvalue);
1908 i = ccitem->link - 1;
1909 }
1910}

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 1409 of file inval.c.

1410{
1411 /*
1412 * You might think this shouldn't be called outside any transaction, but
1413 * bootstrap does it, and also ABORT issued when not in a transaction. So
1414 * just quietly return if no state to work on.
1415 */
1416 if (transInvalInfo == NULL)
1417 return;
1418
1421
1422 /* WAL Log per-command invalidation messages for wal_level=logical */
1425
1428}
void LogLogicalInvalidations(void)
Definition: inval.c:1935
#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 1286 of file inval.c.

1287{
1288 inplaceInvalInfo = NULL;
1289}

References inplaceInvalInfo.

Referenced by heap_inplace_lock(), and heap_inplace_unlock().

◆ inplaceGetInvalidationMessages()

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

Definition at line 1088 of file inval.c.

1090{
1091 SharedInvalidationMessage *msgarray;
1092 int nummsgs;
1093 int nmsgs;
1094
1095 /* Quick exit if we haven't done anything with invalidation messages. */
1096 if (inplaceInvalInfo == NULL)
1097 {
1098 *RelcacheInitFileInval = false;
1099 *msgs = NULL;
1100 return 0;
1101 }
1102
1103 *RelcacheInitFileInval = inplaceInvalInfo->RelcacheInitFileInval;
1105 *msgs = msgarray = (SharedInvalidationMessage *)
1106 palloc(nummsgs * sizeof(SharedInvalidationMessage));
1107
1108 nmsgs = 0;
1111 (memcpy(msgarray + nmsgs,
1112 msgs,
1113 n * sizeof(SharedInvalidationMessage)),
1114 nmsgs += n));
1117 (memcpy(msgarray + nmsgs,
1118 msgs,
1119 n * sizeof(SharedInvalidationMessage)),
1120 nmsgs += n));
1121 Assert(nmsgs == nummsgs);
1122
1123 return nmsgs;
1124}
#define NumMessagesInGroup(group)
Definition: inval.c:207
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
Definition: inval.c:402
void * palloc(Size size)
Definition: mcxt.c:1945

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 785 of file inval.c.

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

824{
825 if (msg->id >= 0)
826 {
827 if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid)
828 {
830
831 SysCacheInvalidate(msg->cc.id, msg->cc.hashValue);
832
834 }
835 }
836 else if (msg->id == SHAREDINVALCATALOG_ID)
837 {
838 if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid)
839 {
841
843
844 /* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */
845 }
846 }
847 else if (msg->id == SHAREDINVALRELCACHE_ID)
848 {
849 if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid)
850 {
851 int i;
852
853 if (msg->rc.relId == InvalidOid)
855 else
857
858 for (i = 0; i < relcache_callback_count; i++)
859 {
860 struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
861
862 ccitem->function(ccitem->arg, msg->rc.relId);
863 }
864 }
865 }
866 else if (msg->id == SHAREDINVALSMGR_ID)
867 {
868 /*
869 * We could have smgr entries for relations of other databases, so no
870 * short-circuit test is possible here.
871 */
872 RelFileLocatorBackend rlocator;
873
874 rlocator.locator = msg->sm.rlocator;
875 rlocator.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo;
876 smgrreleaserellocator(rlocator);
877 }
878 else if (msg->id == SHAREDINVALRELMAP_ID)
879 {
880 /* We only care about our own database and shared catalogs */
881 if (msg->rm.dbId == InvalidOid)
883 else if (msg->rm.dbId == MyDatabaseId)
885 }
886 else if (msg->id == SHAREDINVALSNAPSHOT_ID)
887 {
888 /* We only care about our own database and shared catalogs */
889 if (msg->sn.dbId == InvalidOid)
891 else if (msg->sn.dbId == MyDatabaseId)
893 }
894 else if (msg->id == SHAREDINVALRELSYNC_ID)
895 {
896 /* We only care about our own database */
897 if (msg->rs.dbId == MyDatabaseId)
899 }
900 else
901 elog(FATAL, "unrecognized SI message ID: %d", msg->id);
902}
void CatalogCacheFlushCatalog(Oid catId)
Definition: catcache.c:834
void CallRelSyncCallbacks(Oid relid)
Definition: inval.c:1916
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1894
void RelationCacheInvalidateEntry(Oid relationId)
Definition: relcache.c:2938
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 1935 of file inval.c.

1936{
1937 xl_xact_invals xlrec;
1938 InvalidationMsgsGroup *group;
1939 int nmsgs;
1940
1941 /* Quick exit if we haven't done anything with invalidation messages. */
1942 if (transInvalInfo == NULL)
1943 return;
1944
1946 nmsgs = NumMessagesInGroup(group);
1947
1948 if (nmsgs > 0)
1949 {
1950 /* prepare record */
1951 memset(&xlrec, 0, MinSizeOfXactInvals);
1952 xlrec.nmsgs = nmsgs;
1953
1954 /* perform insertion */
1958 XLogRegisterData(msgs,
1959 n * sizeof(SharedInvalidationMessage)));
1961 XLogRegisterData(msgs,
1962 n * sizeof(SharedInvalidationMessage)));
1964 }
1965}
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 993 of file inval.c.

994{
995 AtEOXact_Inval(false);
996}
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1199

References AtEOXact_Inval().

Referenced by PrepareTransaction().

◆ PreInplace_Inval()

◆ PrepareInplaceInvalidationState()

static InvalidationInfo * PrepareInplaceInvalidationState ( void  )
static

Definition at line 752 of file inval.c.

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

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

References Assert(), AssertCouldGetRelation(), CatCacheMsgs, InvalidationInfo::CurrentCmdInvalidMsgs, elog, ERROR, GetCurrentTransactionNestLevel(), TransInvalidationInfo::ii, inplaceInvalInfo, InvalMessageArrays, 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 1135 of file inval.c.

1138{
1139 if (nmsgs <= 0)
1140 return;
1141
1142 elog(DEBUG4, "replaying commit with %d messages%s", nmsgs,
1143 (RelcacheInitFileInval ? " and relcache file invalidation" : ""));
1144
1145 if (RelcacheInitFileInval)
1146 {
1147 elog(DEBUG4, "removing relcache init files for database %u", dbid);
1148
1149 /*
1150 * RelationCacheInitFilePreInvalidate, when the invalidation message
1151 * is for a specific database, requires DatabasePath to be set, but we
1152 * should not use SetDatabasePath during recovery, since it is
1153 * intended to be used only once by normal backends. Hence, a quick
1154 * hack: set DatabasePath directly then unset after use.
1155 */
1156 if (OidIsValid(dbid))
1157 DatabasePath = GetDatabasePath(dbid, tsid);
1158
1160
1161 if (OidIsValid(dbid))
1162 {
1164 DatabasePath = NULL;
1165 }
1166 }
1167
1168 SendSharedInvalidMessages(msgs, nmsgs);
1169
1170 if (RelcacheInitFileInval)
1172}
#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:6817
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 1012 of file inval.c.

1014{
1015 SharedInvalidationMessage *msgarray;
1016 int nummsgs;
1017 int nmsgs;
1018
1019 /* Quick exit if we haven't done anything with invalidation messages. */
1020 if (transInvalInfo == NULL)
1021 {
1022 *RelcacheInitFileInval = false;
1023 *msgs = NULL;
1024 return 0;
1025 }
1026
1027 /* Must be at top of stack */
1029
1030 /*
1031 * Relcache init file invalidation requires processing both before and
1032 * after we send the SI messages. However, we need not do anything unless
1033 * we committed.
1034 */
1035 *RelcacheInitFileInval = transInvalInfo->ii.RelcacheInitFileInval;
1036
1037 /*
1038 * Collect all the pending messages into a single contiguous array of
1039 * invalidation messages, to simplify what needs to happen while building
1040 * the commit WAL message. Maintain the order that they would be
1041 * processed in by AtEOXact_Inval(), to ensure emulated behaviour in redo
1042 * is as similar as possible to original. We want the same bugs, if any,
1043 * not new ones.
1044 */
1047
1048 *msgs = msgarray = (SharedInvalidationMessage *)
1050 nummsgs * sizeof(SharedInvalidationMessage));
1051
1052 nmsgs = 0;
1055 (memcpy(msgarray + nmsgs,
1056 msgs,
1057 n * sizeof(SharedInvalidationMessage)),
1058 nmsgs += n));
1061 (memcpy(msgarray + nmsgs,
1062 msgs,
1063 n * sizeof(SharedInvalidationMessage)),
1064 nmsgs += n));
1067 (memcpy(msgarray + nmsgs,
1068 msgs,
1069 n * sizeof(SharedInvalidationMessage)),
1070 nmsgs += n));
1073 (memcpy(msgarray + nmsgs,
1074 msgs,
1075 n * sizeof(SharedInvalidationMessage)),
1076 nmsgs += n));
1077 Assert(nmsgs == nummsgs);
1078
1079 return nmsgs;
1080}
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