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 "catalog/catalog.h"
#include "catalog/pg_constraint.h"
#include "miscadmin.h"
#include "storage/sinval.h"
#include "storage/smgr.h"
#include "utils/catcache.h"
#include "utils/guc.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  TransInvalidationInfo
 
struct  SYSCACHECALLBACK
 
struct  RELCACHECALLBACK
 

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 ProcessMessageSubGroup(group, subgroup, codeFragment)
 
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
 

Typedefs

typedef struct InvalMessageArray InvalMessageArray
 
typedef struct InvalidationMsgsGroup InvalidationMsgsGroup
 
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 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)
 
static void RegisterCatalogInvalidation (Oid dbId, Oid catId)
 
static void RegisterRelcacheInvalidation (Oid dbId, Oid relId)
 
static void RegisterSnapshotInvalidation (Oid dbId, Oid relId)
 
void LocalExecuteInvalidationMessage (SharedInvalidationMessage *msg)
 
void InvalidateSystemCaches (void)
 
void AcceptInvalidationMessages (void)
 
static void PrepareInvalidationState (void)
 
void PostPrepare_Inval (void)
 
int xactGetCommittedInvalidationMessages (SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
 
void ProcessCommittedInvalidationMessages (SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
 
void AtEOXact_Inval (bool isCommit)
 
void AtEOSubXact_Inval (bool isCommit)
 
void CommandEndInvalidationMessages (void)
 
void CacheInvalidateHeapTuple (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 CacheInvalidateSmgr (RelFileNodeBackend rnode)
 
void CacheInvalidateRelmap (Oid databaseId)
 
void CacheRegisterSyscacheCallback (int cacheid, SyscacheCallbackFunction func, Datum arg)
 
void CacheRegisterRelcacheCallback (RelcacheCallbackFunction func, Datum arg)
 
void CallSyscacheCallbacks (int cacheid, uint32 hashvalue)
 
void LogLogicalInvalidations (void)
 

Variables

static InvalMessageArray InvalMessageArrays [2]
 
static TransInvalidationInfotransInvalInfo = 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
 

Macro Definition Documentation

◆ CatCacheMsgs

◆ MAX_RELCACHE_CALLBACKS

#define MAX_RELCACHE_CALLBACKS   10

Definition at line 239 of file inval.c.

Referenced by CacheRegisterRelcacheCallback().

◆ MAX_SYSCACHE_CALLBACKS

#define MAX_SYSCACHE_CALLBACKS   64

Definition at line 238 of file inval.c.

Referenced by CacheRegisterSyscacheCallback().

◆ NumMessagesInGroup

#define NumMessagesInGroup (   group)
Value:
NumMessagesInSubGroup(group, RelCacheMsgs))
#define RelCacheMsgs
Definition: inval.c:148
#define CatCacheMsgs
Definition: inval.c:147
#define NumMessagesInSubGroup(group, subgroup)
Definition: inval.c:180

Definition at line 183 of file inval.c.

Referenced by LogLogicalInvalidations(), PrepareInvalidationState(), and xactGetCommittedInvalidationMessages().

◆ NumMessagesInSubGroup

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

Definition at line 180 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)
SharedInvalidationMessage * msgs
Definition: inval.c:153
static InvalMessageArray InvalMessageArrays[2]
Definition: inval.c:157

Definition at line 340 of file inval.c.

Referenced by AddRelcacheInvalidationMessage(), AddSnapshotInvalidationMessage(), and ProcessInvalidationMessages().

◆ 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)
SharedInvalidationMessage * msgs
Definition: inval.c:153
static InvalMessageArray InvalMessageArrays[2]
Definition: inval.c:157
#define NumMessagesInSubGroup(group, subgroup)
Definition: inval.c:180

Definition at line 358 of file inval.c.

Referenced by LogLogicalInvalidations(), ProcessInvalidationMessagesMulti(), and xactGetCommittedInvalidationMessages().

◆ RelCacheMsgs

◆ SetGroupToFollow

#define SetGroupToFollow (   targetgroup,
  priorgroup 
)
Value:
do { \
SetSubGroupToFollow(targetgroup, priorgroup, CatCacheMsgs); \
SetSubGroupToFollow(targetgroup, priorgroup, RelCacheMsgs); \
} while (0)
#define RelCacheMsgs
Definition: inval.c:148
#define CatCacheMsgs
Definition: inval.c:147

Definition at line 174 of file inval.c.

Referenced by AtEOSubXact_Inval(), and PrepareInvalidationState().

◆ SetSubGroupToFollow

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

Definition at line 167 of file inval.c.

Referenced by AppendInvalidationMessageSubGroup().

Typedef Documentation

◆ InvalidationMsgsGroup

◆ InvalMessageArray

◆ TransInvalidationInfo

Function Documentation

◆ AcceptInvalidationMessages()

void AcceptInvalidationMessages ( void  )

Definition at line 725 of file inval.c.

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

Referenced by apply_handle_commit_internal(), AtStart_Cache(), ConditionalLockRelation(), ConditionalLockRelationOid(), delay_execution_planner(), InitializeSessionUserId(), LockDatabaseObject(), LockRelation(), LockRelationOid(), LockSharedObject(), LogicalRepApplyLoop(), ProcessCatchupInterrupt(), RangeVarGetRelidExtended(), relation_openrv(), relation_openrv_extended(), RemoveRelations(), and write_relcache_init_file().

726 {
729 
730  /*----------
731  * Test code to force cache flushes anytime a flush could happen.
732  *
733  * This helps detect intermittent faults caused by code that reads a cache
734  * entry and then performs an action that could invalidate the entry, but
735  * rarely actually does so. This can spot issues that would otherwise
736  * only arise with badly timed concurrent DDL, for example.
737  *
738  * The default debug_discard_caches = 0 does no forced cache flushes.
739  *
740  * If used with CLOBBER_FREED_MEMORY,
741  * debug_discard_caches = 1 (formerly known as CLOBBER_CACHE_ALWAYS)
742  * provides a fairly thorough test that the system contains no cache-flush
743  * hazards. However, it also makes the system unbelievably slow --- the
744  * regression tests take about 100 times longer than normal.
745  *
746  * If you're a glutton for punishment, try
747  * debug_discard_caches = 3 (formerly known as CLOBBER_CACHE_RECURSIVELY).
748  * This slows things by at least a factor of 10000, so I wouldn't suggest
749  * trying to run the entire regression tests that way. It's useful to try
750  * a few simple tests, to make sure that cache reload isn't subject to
751  * internal cache-flush hazards, but after you've done a few thousand
752  * recursive reloads it's unlikely you'll learn more.
753  *----------
754  */
755 #ifdef DISCARD_CACHES_ENABLED
756  {
757  static int recursion_depth = 0;
758 
759  if (recursion_depth < debug_discard_caches)
760  {
761  recursion_depth++;
763  recursion_depth--;
764  }
765  }
766 #endif
767 }
static int recursion_depth
Definition: elog.c:149
int debug_discard_caches
Definition: inval.c:226
void InvalidateSystemCaches(void)
Definition: inval.c:687
void ReceiveSharedInvalidMessages(void(*invalFunction)(SharedInvalidationMessage *msg), void(*resetFunction)(void))
Definition: sinval.c:71
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:600

◆ AddCatalogInvalidationMessage()

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

Definition at line 409 of file inval.c.

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

Referenced by RegisterCatalogInvalidation().

411 {
413 
415  msg.cat.dbId = dbId;
416  msg.cat.catId = catId;
417  /* check AddCatcacheInvalidationMessage() for an explanation */
418  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
419 
420  AddInvalidationMessage(group, CatCacheMsgs, &msg);
421 }
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
#define CatCacheMsgs
Definition: inval.c:147
static void AddInvalidationMessage(InvalidationMsgsGroup *group, int subgroup, const SharedInvalidationMessage *msg)
Definition: inval.c:276
SharedInvalCatalogMsg cat
Definition: sinval.h:117
#define SHAREDINVALCATALOG_ID
Definition: sinval.h:67

◆ AddCatcacheInvalidationMessage()

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

Definition at line 381 of file inval.c.

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

Referenced by RegisterCatcacheInvalidation().

383 {
385 
386  Assert(id < CHAR_MAX);
387  msg.cc.id = (int8) id;
388  msg.cc.dbId = dbId;
389  msg.cc.hashValue = hashValue;
390 
391  /*
392  * Define padding bytes in SharedInvalidationMessage structs to be
393  * defined. Otherwise the sinvaladt.c ringbuffer, which is accessed by
394  * multiple processes, will cause spurious valgrind warnings about
395  * undefined memory being used. That's because valgrind remembers the
396  * undefined bytes from the last local process's store, not realizing that
397  * another process has written since, filling the previously uninitialized
398  * bytes
399  */
400  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
401 
402  AddInvalidationMessage(group, CatCacheMsgs, &msg);
403 }
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
#define CatCacheMsgs
Definition: inval.c:147
static void AddInvalidationMessage(InvalidationMsgsGroup *group, int subgroup, const SharedInvalidationMessage *msg)
Definition: inval.c:276
SharedInvalCatcacheMsg cc
Definition: sinval.h:116
signed char int8
Definition: c.h:427
#define Assert(condition)
Definition: c.h:804

◆ AddInvalidationMessage()

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

Definition at line 276 of file inval.c.

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

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

278 {
279  InvalMessageArray *ima = &InvalMessageArrays[subgroup];
280  int nextindex = group->nextmsg[subgroup];
281 
282  if (nextindex >= ima->maxmsgs)
283  {
284  if (ima->msgs == NULL)
285  {
286  /* Create new storage array in TopTransactionContext */
287  int reqsize = 32; /* arbitrary */
288 
291  reqsize * sizeof(SharedInvalidationMessage));
292  ima->maxmsgs = reqsize;
293  Assert(nextindex == 0);
294  }
295  else
296  {
297  /* Enlarge storage array */
298  int reqsize = 2 * ima->maxmsgs;
299 
301  repalloc(ima->msgs,
302  reqsize * sizeof(SharedInvalidationMessage));
303  ima->maxmsgs = reqsize;
304  }
305  }
306  /* Okay, add message to current group */
307  ima->msgs[nextindex] = *msg;
308  group->nextmsg[subgroup]++;
309 }
MemoryContext TopTransactionContext
Definition: mcxt.c:53
SharedInvalidationMessage * msgs
Definition: inval.c:153
static InvalMessageArray InvalMessageArrays[2]
Definition: inval.c:157
#define Assert(condition)
Definition: c.h:804
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863

◆ AddRelcacheInvalidationMessage()

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

Definition at line 427 of file inval.c.

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

Referenced by RegisterRelcacheInvalidation().

429 {
431 
432  /*
433  * Don't add a duplicate item. We assume dbId need not be checked because
434  * it will never change. InvalidOid for relId means all relations so we
435  * don't need to add individual ones when it is present.
436  */
438  if (msg->rc.id == SHAREDINVALRELCACHE_ID &&
439  (msg->rc.relId == relId ||
440  msg->rc.relId == InvalidOid))
441  return);
442 
443  /* OK, add the item */
445  msg.rc.dbId = dbId;
446  msg.rc.relId = relId;
447  /* check AddCatcacheInvalidationMessage() for an explanation */
448  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
449 
450  AddInvalidationMessage(group, RelCacheMsgs, &msg);
451 }
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
SharedInvalRelcacheMsg rc
Definition: sinval.h:118
#define RelCacheMsgs
Definition: inval.c:148
static void AddInvalidationMessage(InvalidationMsgsGroup *group, int subgroup, const SharedInvalidationMessage *msg)
Definition: inval.c:276
#define SHAREDINVALRELCACHE_ID
Definition: sinval.h:76
#define InvalidOid
Definition: postgres_ext.h:36
#define ProcessMessageSubGroup(group, subgroup, codeFragment)
Definition: inval.c:340

◆ AddSnapshotInvalidationMessage()

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

Definition at line 459 of file inval.c.

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

Referenced by RegisterSnapshotInvalidation().

461 {
463 
464  /* Don't add a duplicate item */
465  /* We assume dbId need not be checked because it will never change */
467  if (msg->sn.id == SHAREDINVALSNAPSHOT_ID &&
468  msg->sn.relId == relId)
469  return);
470 
471  /* OK, add the item */
473  msg.sn.dbId = dbId;
474  msg.sn.relId = relId;
475  /* check AddCatcacheInvalidationMessage() for an explanation */
476  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
477 
478  AddInvalidationMessage(group, RelCacheMsgs, &msg);
479 }
SharedInvalSnapshotMsg sn
Definition: sinval.h:121
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
#define RelCacheMsgs
Definition: inval.c:148
static void AddInvalidationMessage(InvalidationMsgsGroup *group, int subgroup, const SharedInvalidationMessage *msg)
Definition: inval.c:276
#define SHAREDINVALSNAPSHOT_ID
Definition: sinval.h:104
#define ProcessMessageSubGroup(group, subgroup, codeFragment)
Definition: inval.c:340

◆ AppendInvalidationMessages()

static void AppendInvalidationMessages ( InvalidationMsgsGroup dest,
InvalidationMsgsGroup src 
)
static

Definition at line 486 of file inval.c.

References AppendInvalidationMessageSubGroup(), CatCacheMsgs, and RelCacheMsgs.

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

488 {
491 }
#define RelCacheMsgs
Definition: inval.c:148
#define CatCacheMsgs
Definition: inval.c:147
static void AppendInvalidationMessageSubGroup(InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src, int subgroup)
Definition: inval.c:316

◆ AppendInvalidationMessageSubGroup()

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

Definition at line 316 of file inval.c.

References Assert, InvalidationMsgsGroup::firstmsg, InvalidationMsgsGroup::nextmsg, and SetSubGroupToFollow.

Referenced by AppendInvalidationMessages().

319 {
320  /* Messages must be adjacent in main array */
321  Assert(dest->nextmsg[subgroup] == src->firstmsg[subgroup]);
322 
323  /* ... which makes this easy: */
324  dest->nextmsg[subgroup] = src->nextmsg[subgroup];
325 
326  /*
327  * This is handy for some callers and irrelevant for others. But we do it
328  * always, reasoning that it's bad to leave different groups pointing at
329  * the same fragment of the message array.
330  */
331  SetSubGroupToFollow(src, dest, subgroup);
332 }
#define SetSubGroupToFollow(targetgroup, priorgroup, subgroup)
Definition: inval.c:167
#define Assert(condition)
Definition: c.h:804

◆ AtEOSubXact_Inval()

void AtEOSubXact_Inval ( bool  isCommit)

Definition at line 1064 of file inval.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

1065 {
1066  int my_level;
1068 
1069  /* Quick exit if no messages. */
1070  if (myInfo == NULL)
1071  return;
1072 
1073  /* Also bail out quickly if messages are not for this level. */
1074  my_level = GetCurrentTransactionNestLevel();
1075  if (myInfo->my_level != my_level)
1076  {
1077  Assert(myInfo->my_level < my_level);
1078  return;
1079  }
1080 
1081  if (isCommit)
1082  {
1083  /* If CurrentCmdInvalidMsgs still has anything, fix it */
1085 
1086  /*
1087  * We create invalidation stack entries lazily, so the parent might
1088  * not have one. Instead of creating one, moving all the data over,
1089  * and then freeing our own, we can just adjust the level of our own
1090  * entry.
1091  */
1092  if (myInfo->parent == NULL || myInfo->parent->my_level < my_level - 1)
1093  {
1094  myInfo->my_level--;
1095  return;
1096  }
1097 
1098  /*
1099  * Pass up my inval messages to parent. Notice that we stick them in
1100  * PriorCmdInvalidMsgs, not CurrentCmdInvalidMsgs, since they've
1101  * already been locally processed. (This would trigger the Assert in
1102  * AppendInvalidationMessageSubGroup if the parent's
1103  * CurrentCmdInvalidMsgs isn't empty; but we already checked that in
1104  * PrepareInvalidationState.)
1105  */
1107  &myInfo->PriorCmdInvalidMsgs);
1108 
1109  /* Must readjust parent's CurrentCmdInvalidMsgs indexes now */
1111  &myInfo->parent->PriorCmdInvalidMsgs);
1112 
1113  /* Pending relcache inval becomes parent's problem too */
1114  if (myInfo->RelcacheInitFileInval)
1115  myInfo->parent->RelcacheInitFileInval = true;
1116 
1117  /* Pop the transaction state stack */
1118  transInvalInfo = myInfo->parent;
1119 
1120  /* Need not free anything else explicitly */
1121  pfree(myInfo);
1122  }
1123  else
1124  {
1127 
1128  /* Pop the transaction state stack */
1129  transInvalInfo = myInfo->parent;
1130 
1131  /* Need not free anything else explicitly */
1132  pfree(myInfo);
1133  }
1134 }
void CommandEndInvalidationMessages(void)
Definition: inval.c:1152
struct TransInvalidationInfo * parent
Definition: inval.c:208
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
void pfree(void *pointer)
Definition: mcxt.c:1169
bool RelcacheInitFileInval
Definition: inval.c:220
static void ProcessInvalidationMessages(InvalidationMsgsGroup *group, void(*func)(SharedInvalidationMessage *msg))
Definition: inval.c:500
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
#define Assert(condition)
Definition: c.h:804
#define SetGroupToFollow(targetgroup, priorgroup)
Definition: inval.c:174
InvalidationMsgsGroup PriorCmdInvalidMsgs
Definition: inval.c:217
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:600
static void AppendInvalidationMessages(InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src)
Definition: inval.c:486
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214

◆ AtEOXact_Inval()

void AtEOXact_Inval ( bool  isCommit)

Definition at line 1007 of file inval.c.

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

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

1008 {
1009  /* Quick exit if no messages */
1010  if (transInvalInfo == NULL)
1011  return;
1012 
1013  /* Must be at top of stack */
1014  Assert(transInvalInfo->my_level == 1 && transInvalInfo->parent == NULL);
1015 
1016  if (isCommit)
1017  {
1018  /*
1019  * Relcache init file invalidation requires processing both before and
1020  * after we send the SI messages. However, we need not do anything
1021  * unless we committed.
1022  */
1025 
1028 
1031 
1034  }
1035  else
1036  {
1039  }
1040 
1041  /* Need not free anything explicitly */
1042  transInvalInfo = NULL;
1043 }
struct TransInvalidationInfo * parent
Definition: inval.c:208
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
bool RelcacheInitFileInval
Definition: inval.c:220
static void ProcessInvalidationMessages(InvalidationMsgsGroup *group, void(*func)(SharedInvalidationMessage *msg))
Definition: inval.c:500
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6465
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6440
#define Assert(condition)
Definition: c.h:804
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:49
InvalidationMsgsGroup PriorCmdInvalidMsgs
Definition: inval.c:217
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:600
static void AppendInvalidationMessages(InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src)
Definition: inval.c:486
static void ProcessInvalidationMessagesMulti(InvalidationMsgsGroup *group, void(*func)(const SharedInvalidationMessage *msgs, int n))
Definition: inval.c:512
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214

◆ CacheInvalidateCatalog()

void CacheInvalidateCatalog ( Oid  catalogId)

Definition at line 1318 of file inval.c.

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

Referenced by finish_heap_swap().

1319 {
1320  Oid databaseId;
1321 
1323 
1324  if (IsSharedRelation(catalogId))
1325  databaseId = InvalidOid;
1326  else
1327  databaseId = MyDatabaseId;
1328 
1329  RegisterCatalogInvalidation(databaseId, catalogId);
1330 }
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:774
Oid MyDatabaseId
Definition: globals.c:88
static void RegisterCatalogInvalidation(Oid dbId, Oid catId)
Definition: inval.c:544
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:244
#define InvalidOid
Definition: postgres_ext.h:36

◆ CacheInvalidateHeapTuple()

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

Definition at line 1186 of file inval.c.

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

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

1189 {
1190  Oid tupleRelId;
1191  Oid databaseId;
1192  Oid relationId;
1193 
1194  /* Do nothing during bootstrap */
1196  return;
1197 
1198  /*
1199  * We only need to worry about invalidation for tuples that are in system
1200  * catalogs; user-relation tuples are never in catcaches and can't affect
1201  * the relcache either.
1202  */
1203  if (!IsCatalogRelation(relation))
1204  return;
1205 
1206  /*
1207  * IsCatalogRelation() will return true for TOAST tables of system
1208  * catalogs, but we don't care about those, either.
1209  */
1210  if (IsToastRelation(relation))
1211  return;
1212 
1213  /*
1214  * If we're not prepared to queue invalidation messages for this
1215  * subtransaction level, get ready now.
1216  */
1218 
1219  /*
1220  * First let the catcache do its thing
1221  */
1222  tupleRelId = RelationGetRelid(relation);
1223  if (RelationInvalidatesSnapshotsOnly(tupleRelId))
1224  {
1225  databaseId = IsSharedRelation(tupleRelId) ? InvalidOid : MyDatabaseId;
1226  RegisterSnapshotInvalidation(databaseId, tupleRelId);
1227  }
1228  else
1229  PrepareToInvalidateCacheTuple(relation, tuple, newtuple,
1231 
1232  /*
1233  * Now, is this tuple one of the primary definers of a relcache entry? See
1234  * comments in file header for deeper explanation.
1235  *
1236  * Note we ignore newtuple here; we assume an update cannot move a tuple
1237  * from being part of one relcache entry to being part of another.
1238  */
1239  if (tupleRelId == RelationRelationId)
1240  {
1241  Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple);
1242 
1243  relationId = classtup->oid;
1244  if (classtup->relisshared)
1245  databaseId = InvalidOid;
1246  else
1247  databaseId = MyDatabaseId;
1248  }
1249  else if (tupleRelId == AttributeRelationId)
1250  {
1251  Form_pg_attribute atttup = (Form_pg_attribute) GETSTRUCT(tuple);
1252 
1253  relationId = atttup->attrelid;
1254 
1255  /*
1256  * KLUGE ALERT: we always send the relcache event with MyDatabaseId,
1257  * even if the rel in question is shared (which we can't easily tell).
1258  * This essentially means that only backends in this same database
1259  * will react to the relcache flush request. This is in fact
1260  * appropriate, since only those backends could see our pg_attribute
1261  * change anyway. It looks a bit ugly though. (In practice, shared
1262  * relations can't have schema changes after bootstrap, so we should
1263  * never come here for a shared rel anyway.)
1264  */
1265  databaseId = MyDatabaseId;
1266  }
1267  else if (tupleRelId == IndexRelationId)
1268  {
1269  Form_pg_index indextup = (Form_pg_index) GETSTRUCT(tuple);
1270 
1271  /*
1272  * When a pg_index row is updated, we should send out a relcache inval
1273  * for the index relation. As above, we don't know the shared status
1274  * of the index, but in practice it doesn't matter since indexes of
1275  * shared catalogs can't have such updates.
1276  */
1277  relationId = indextup->indexrelid;
1278  databaseId = MyDatabaseId;
1279  }
1280  else if (tupleRelId == ConstraintRelationId)
1281  {
1282  Form_pg_constraint constrtup = (Form_pg_constraint) GETSTRUCT(tuple);
1283 
1284  /*
1285  * Foreign keys are part of relcache entries, too, so send out an
1286  * inval for the table that the FK applies to.
1287  */
1288  if (constrtup->contype == CONSTRAINT_FOREIGN &&
1289  OidIsValid(constrtup->conrelid))
1290  {
1291  relationId = constrtup->conrelid;
1292  databaseId = MyDatabaseId;
1293  }
1294  else
1295  return;
1296  }
1297  else
1298  return;
1299 
1300  /*
1301  * Yes. We need to register a relcache invalidation event.
1302  */
1303  RegisterRelcacheInvalidation(databaseId, relationId);
1304 }
bool IsToastRelation(Relation relation)
Definition: catalog.c:146
bool IsCatalogRelation(Relation relation)
Definition: catalog.c:104
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
void PrepareToInvalidateCacheTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid))
Definition: catcache.c:2009
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
static void PrepareInvalidationState(void)
Definition: inval.c:774
FormData_pg_index * Form_pg_index
Definition: pg_index.h:69
Oid MyDatabaseId
Definition: globals.c:88
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:244
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:556
FormData_pg_constraint * Form_pg_constraint
static void RegisterCatcacheInvalidation(int cacheId, uint32 hashValue, Oid dbId)
Definition: inval.c:530
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition: syscache.c:1484
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define RelationGetRelid(relation)
Definition: rel.h:477
static void RegisterSnapshotInvalidation(Oid dbId, Oid relId)
Definition: inval.c:586

◆ CacheInvalidateRelcache()

void CacheInvalidateRelcache ( Relation  relation)

Definition at line 1342 of file inval.c.

References InvalidOid, MyDatabaseId, PrepareInvalidationState(), RelationData::rd_rel, RegisterRelcacheInvalidation(), and RelationGetRelid.

Referenced by AlterPolicy(), ATExecAlterConstrRecurse(), ATExecDetachPartition(), ATExecGenericOptions(), ATExecValidateConstraint(), CreatePolicy(), CreateStatistics(), DetachPartitionFinalize(), EnableDisableRule(), EnableDisableTrigger(), index_concurrently_set_dead(), index_create(), index_drop(), reindex_index(), RelationSetNewRelfilenode(), RemovePolicyById(), RemoveRewriteRuleById(), RemoveTriggerById(), rename_constraint_internal(), rename_policy(), RenameRewriteRule(), renametrig_internal(), SetRelationNumChecks(), StorePartitionBound(), and StorePartitionKey().

1343 {
1344  Oid databaseId;
1345  Oid relationId;
1346 
1348 
1349  relationId = RelationGetRelid(relation);
1350  if (relation->rd_rel->relisshared)
1351  databaseId = InvalidOid;
1352  else
1353  databaseId = MyDatabaseId;
1354 
1355  RegisterRelcacheInvalidation(databaseId, relationId);
1356 }
Form_pg_class rd_rel
Definition: rel.h:109
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:774
Oid MyDatabaseId
Definition: globals.c:88
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:556
#define RelationGetRelid(relation)
Definition: rel.h:477

◆ CacheInvalidateRelcacheAll()

void CacheInvalidateRelcacheAll ( void  )

Definition at line 1366 of file inval.c.

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

Referenced by AlterPublicationOptions(), CreatePublication(), InvalidatePublicationRels(), and RemovePublicationById().

1367 {
1369 
1371 }
static void PrepareInvalidationState(void)
Definition: inval.c:774
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:556

◆ CacheInvalidateRelcacheByRelid()

void CacheInvalidateRelcacheByRelid ( Oid  relid)

Definition at line 1401 of file inval.c.

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

Referenced by ATExecAlterConstraint(), DefineIndex(), DetachPartitionFinalize(), heap_drop_with_catalog(), InvalidatePublicationRels(), ReindexRelationConcurrently(), RemoveStatisticsById(), and StorePartitionBound().

1402 {
1403  HeapTuple tup;
1404 
1406 
1407  tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1408  if (!HeapTupleIsValid(tup))
1409  elog(ERROR, "cache lookup failed for relation %u", relid);
1411  ReleaseSysCache(tup);
1412 }
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
static void PrepareInvalidationState(void)
Definition: inval.c:774
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:232
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
Definition: inval.c:1378

◆ CacheInvalidateRelcacheByTuple()

void CacheInvalidateRelcacheByTuple ( HeapTuple  classTuple)

Definition at line 1378 of file inval.c.

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

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

1379 {
1380  Form_pg_class classtup = (Form_pg_class) GETSTRUCT(classTuple);
1381  Oid databaseId;
1382  Oid relationId;
1383 
1385 
1386  relationId = classtup->oid;
1387  if (classtup->relisshared)
1388  databaseId = InvalidOid;
1389  else
1390  databaseId = MyDatabaseId;
1391  RegisterRelcacheInvalidation(databaseId, relationId);
1392 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:774
Oid MyDatabaseId
Definition: globals.c:88
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:556
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153

◆ CacheInvalidateRelmap()

void CacheInvalidateRelmap ( Oid  databaseId)

Definition at line 1471 of file inval.c.

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

Referenced by write_relmap_file().

1472 {
1474 
1475  msg.rm.id = SHAREDINVALRELMAP_ID;
1476  msg.rm.dbId = databaseId;
1477  /* check AddCatcacheInvalidationMessage() for an explanation */
1478  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1479 
1480  SendSharedInvalidMessages(&msg, 1);
1481 }
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
SharedInvalRelmapMsg rm
Definition: sinval.h:120
#define SHAREDINVALRELMAP_ID
Definition: sinval.h:96
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:49

◆ CacheInvalidateSmgr()

void CacheInvalidateSmgr ( RelFileNodeBackend  rnode)

Definition at line 1441 of file inval.c.

References RelFileNodeBackend::backend, SharedInvalSmgrMsg::backend_hi, SharedInvalSmgrMsg::backend_lo, SharedInvalSmgrMsg::id, RelFileNodeBackend::node, SharedInvalSmgrMsg::rnode, SendSharedInvalidMessages(), SHAREDINVALSMGR_ID, SharedInvalidationMessage::sm, and VALGRIND_MAKE_MEM_DEFINED.

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

1442 {
1444 
1445  msg.sm.id = SHAREDINVALSMGR_ID;
1446  msg.sm.backend_hi = rnode.backend >> 16;
1447  msg.sm.backend_lo = rnode.backend & 0xffff;
1448  msg.sm.rnode = rnode.node;
1449  /* check AddCatcacheInvalidationMessage() for an explanation */
1450  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1451 
1452  SendSharedInvalidMessages(&msg, 1);
1453 }
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
RelFileNode node
Definition: relfilenode.h:74
SharedInvalSmgrMsg sm
Definition: sinval.h:119
BackendId backend
Definition: relfilenode.h:75
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:49
uint16 backend_lo
Definition: sinval.h:92
RelFileNode rnode
Definition: sinval.h:93
#define SHAREDINVALSMGR_ID
Definition: sinval.h:85

◆ CacheRegisterRelcacheCallback()

void CacheRegisterRelcacheCallback ( RelcacheCallbackFunction  func,
Datum  arg 
)

Definition at line 1540 of file inval.c.

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

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

1542 {
1544  elog(FATAL, "out of relcache_callback_list slots");
1545 
1548 
1550 }
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
#define MAX_RELCACHE_CALLBACKS
Definition: inval.c:239
static int relcache_callback_count
Definition: inval.c:259
RelcacheCallbackFunction function
Definition: inval.c:255
#define FATAL
Definition: elog.h:49
#define elog(elevel,...)
Definition: elog.h:232
void * arg

◆ CacheRegisterSyscacheCallback()

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

Definition at line 1498 of file inval.c.

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

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

1501 {
1502  if (cacheid < 0 || cacheid >= SysCacheSize)
1503  elog(FATAL, "invalid cache ID: %d", cacheid);
1505  elog(FATAL, "out of syscache_callback_list slots");
1506 
1507  if (syscache_callback_links[cacheid] == 0)
1508  {
1509  /* first callback for this cache */
1511  }
1512  else
1513  {
1514  /* add to end of chain, so that older callbacks are called first */
1515  int i = syscache_callback_links[cacheid] - 1;
1516 
1517  while (syscache_callback_list[i].link > 0)
1518  i = syscache_callback_list[i].link - 1;
1520  }
1521 
1526 
1528 }
int16 link
Definition: inval.c:244
#define SysCacheSize
Definition: syscache.h:114
#define FATAL
Definition: elog.h:49
#define MAX_SYSCACHE_CALLBACKS
Definition: inval.c:238
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
static int syscache_callback_count
Definition: inval.c:251
static int16 syscache_callback_links[SysCacheSize]
Definition: inval.c:249
#define elog(elevel,...)
Definition: elog.h:232
int i
void * arg
SyscacheCallbackFunction function
Definition: inval.c:245

◆ CallSyscacheCallbacks()

void CallSyscacheCallbacks ( int  cacheid,
uint32  hashvalue 
)

Definition at line 1559 of file inval.c.

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

Referenced by CatalogCacheFlushCatalog(), and LocalExecuteInvalidationMessage().

1560 {
1561  int i;
1562 
1563  if (cacheid < 0 || cacheid >= SysCacheSize)
1564  elog(ERROR, "invalid cache ID: %d", cacheid);
1565 
1566  i = syscache_callback_links[cacheid] - 1;
1567  while (i >= 0)
1568  {
1569  struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
1570 
1571  Assert(ccitem->id == cacheid);
1572  ccitem->function(ccitem->arg, cacheid, hashvalue);
1573  i = ccitem->link - 1;
1574  }
1575 }
int16 link
Definition: inval.c:244
#define SysCacheSize
Definition: syscache.h:114
#define ERROR
Definition: elog.h:46
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
#define Assert(condition)
Definition: c.h:804
static int16 syscache_callback_links[SysCacheSize]
Definition: inval.c:249
#define elog(elevel,...)
Definition: elog.h:232
int i
SyscacheCallbackFunction function
Definition: inval.c:245

◆ CommandEndInvalidationMessages()

void CommandEndInvalidationMessages ( void  )

Definition at line 1152 of file inval.c.

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

Referenced by AtCCI_LocalCache(), and AtEOSubXact_Inval().

1153 {
1154  /*
1155  * You might think this shouldn't be called outside any transaction, but
1156  * bootstrap does it, and also ABORT issued when not in a transaction. So
1157  * just quietly return if no state to work on.
1158  */
1159  if (transInvalInfo == NULL)
1160  return;
1161 
1164 
1165  /* WAL Log per-command invalidation messages for wal_level=logical */
1166  if (XLogLogicalInfoActive())
1168 
1171 }
void LogLogicalInvalidations(void)
Definition: inval.c:1586
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
#define XLogLogicalInfoActive()
Definition: xlog.h:183
static void ProcessInvalidationMessages(InvalidationMsgsGroup *group, void(*func)(SharedInvalidationMessage *msg))
Definition: inval.c:500
InvalidationMsgsGroup PriorCmdInvalidMsgs
Definition: inval.c:217
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:600
static void AppendInvalidationMessages(InvalidationMsgsGroup *dest, InvalidationMsgsGroup *src)
Definition: inval.c:486
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214

◆ InvalidateSystemCaches()

void InvalidateSystemCaches ( void  )

Definition at line 687 of file inval.c.

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

Referenced by AcceptInvalidationMessages(), ParallelWorkerMain(), pg_logical_replication_slot_advance(), and pg_logical_slot_get_changes_guts().

688 {
689  int i;
690 
693  RelationCacheInvalidate(); /* gets smgr and relmap too */
694 
695  for (i = 0; i < syscache_callback_count; i++)
696  {
697  struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
698 
699  ccitem->function(ccitem->arg, ccitem->id, 0);
700  }
701 
702  for (i = 0; i < relcache_callback_count; i++)
703  {
704  struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
705 
706  ccitem->function(ccitem->arg, InvalidOid);
707  }
708 }
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
static int relcache_callback_count
Definition: inval.c:259
RelcacheCallbackFunction function
Definition: inval.c:255
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:456
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
static int syscache_callback_count
Definition: inval.c:251
#define InvalidOid
Definition: postgres_ext.h:36
void ResetCatalogCaches(void)
Definition: catcache.c:689
void RelationCacheInvalidate(void)
Definition: relcache.c:2840
int i
SyscacheCallbackFunction function
Definition: inval.c:245

◆ LocalExecuteInvalidationMessage()

void LocalExecuteInvalidationMessage ( SharedInvalidationMessage msg)

Definition at line 600 of file inval.c.

References RELCACHECALLBACK::arg, RelFileNodeBackend::backend, SharedInvalSmgrMsg::backend_hi, SharedInvalSmgrMsg::backend_lo, CallSyscacheCallbacks(), SharedInvalidationMessage::cat, CatalogCacheFlushCatalog(), SharedInvalCatalogMsg::catId, SharedInvalidationMessage::cc, SharedInvalCatcacheMsg::dbId, SharedInvalCatalogMsg::dbId, SharedInvalRelcacheMsg::dbId, SharedInvalRelmapMsg::dbId, SharedInvalSnapshotMsg::dbId, elog, FATAL, RELCACHECALLBACK::function, SharedInvalCatcacheMsg::hashValue, i, SharedInvalCatcacheMsg::id, SharedInvalidationMessage::id, InvalidateCatalogSnapshot(), InvalidOid, MyDatabaseId, RelFileNodeBackend::node, SharedInvalidationMessage::rc, RelationCacheInvalidate(), RelationCacheInvalidateEntry(), RelationMapInvalidate(), relcache_callback_count, relcache_callback_list, SharedInvalRelcacheMsg::relId, SharedInvalidationMessage::rm, SharedInvalSmgrMsg::rnode, SHAREDINVALCATALOG_ID, SHAREDINVALRELCACHE_ID, SHAREDINVALRELMAP_ID, SHAREDINVALSMGR_ID, SHAREDINVALSNAPSHOT_ID, SharedInvalidationMessage::sm, smgrclosenode(), SharedInvalidationMessage::sn, and SysCacheInvalidate().

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

601 {
602  if (msg->id >= 0)
603  {
604  if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid)
605  {
607 
608  SysCacheInvalidate(msg->cc.id, msg->cc.hashValue);
609 
610  CallSyscacheCallbacks(msg->cc.id, msg->cc.hashValue);
611  }
612  }
613  else if (msg->id == SHAREDINVALCATALOG_ID)
614  {
615  if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid)
616  {
618 
620 
621  /* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */
622  }
623  }
624  else if (msg->id == SHAREDINVALRELCACHE_ID)
625  {
626  if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid)
627  {
628  int i;
629 
630  if (msg->rc.relId == InvalidOid)
632  else
634 
635  for (i = 0; i < relcache_callback_count; i++)
636  {
637  struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
638 
639  ccitem->function(ccitem->arg, msg->rc.relId);
640  }
641  }
642  }
643  else if (msg->id == SHAREDINVALSMGR_ID)
644  {
645  /*
646  * We could have smgr entries for relations of other databases, so no
647  * short-circuit test is possible here.
648  */
649  RelFileNodeBackend rnode;
650 
651  rnode.node = msg->sm.rnode;
652  rnode.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo;
653  smgrclosenode(rnode);
654  }
655  else if (msg->id == SHAREDINVALRELMAP_ID)
656  {
657  /* We only care about our own database and shared catalogs */
658  if (msg->rm.dbId == InvalidOid)
659  RelationMapInvalidate(true);
660  else if (msg->rm.dbId == MyDatabaseId)
661  RelationMapInvalidate(false);
662  }
663  else if (msg->id == SHAREDINVALSNAPSHOT_ID)
664  {
665  /* We only care about our own database and shared catalogs */
666  if (msg->sn.dbId == InvalidOid)
668  else if (msg->sn.dbId == MyDatabaseId)
670  }
671  else
672  elog(FATAL, "unrecognized SI message ID: %d", msg->id);
673 }
SharedInvalSnapshotMsg sn
Definition: sinval.h:121
SharedInvalRelcacheMsg rc
Definition: sinval.h:118
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
static int relcache_callback_count
Definition: inval.c:259
RelcacheCallbackFunction function
Definition: inval.c:255
void RelationMapInvalidate(bool shared)
Definition: relmapper.c:403
#define FATAL
Definition: elog.h:49
#define SHAREDINVALRELCACHE_ID
Definition: sinval.h:76
SharedInvalRelmapMsg rm
Definition: sinval.h:120
#define SHAREDINVALRELMAP_ID
Definition: sinval.h:96
SharedInvalCatcacheMsg cc
Definition: sinval.h:116
void smgrclosenode(RelFileNodeBackend rnode)
Definition: smgr.c:310
SharedInvalCatalogMsg cat
Definition: sinval.h:117
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:456
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1559
Oid MyDatabaseId
Definition: globals.c:88
#define InvalidOid
Definition: postgres_ext.h:36
#define SHAREDINVALSNAPSHOT_ID
Definition: sinval.h:104
RelFileNode node
Definition: relfilenode.h:74
SharedInvalSmgrMsg sm
Definition: sinval.h:119
void SysCacheInvalidate(int cacheId, uint32 hashValue)
Definition: syscache.c:1460
void CatalogCacheFlushCatalog(Oid catId)
Definition: catcache.c:719
BackendId backend
Definition: relfilenode.h:75
void RelationCacheInvalidateEntry(Oid relationId)
Definition: relcache.c:2797
uint16 backend_lo
Definition: sinval.h:92
#define SHAREDINVALCATALOG_ID
Definition: sinval.h:67
#define elog(elevel,...)
Definition: elog.h:232
void RelationCacheInvalidate(void)
Definition: relcache.c:2840
int i
RelFileNode rnode
Definition: sinval.h:93
#define SHAREDINVALSMGR_ID
Definition: sinval.h:85

◆ LogLogicalInvalidations()

void LogLogicalInvalidations ( void  )

Definition at line 1586 of file inval.c.

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

Referenced by CommandEndInvalidationMessages(), and RecordTransactionCommit().

1587 {
1588  xl_xact_invals xlrec;
1589  InvalidationMsgsGroup *group;
1590  int nmsgs;
1591 
1592  /* Quick exit if we haven't done anything with invalidation messages. */
1593  if (transInvalInfo == NULL)
1594  return;
1595 
1597  nmsgs = NumMessagesInGroup(group);
1598 
1599  if (nmsgs > 0)
1600  {
1601  /* prepare record */
1602  memset(&xlrec, 0, MinSizeOfXactInvals);
1603  xlrec.nmsgs = nmsgs;
1604 
1605  /* perform insertion */
1606  XLogBeginInsert();
1607  XLogRegisterData((char *) (&xlrec), MinSizeOfXactInvals);
1609  XLogRegisterData((char *) msgs,
1610  n * sizeof(SharedInvalidationMessage)));
1612  XLogRegisterData((char *) msgs,
1613  n * sizeof(SharedInvalidationMessage)));
1614  XLogInsert(RM_XACT_ID, XLOG_XACT_INVALIDATIONS);
1615  }
1616 }
#define XLOG_XACT_INVALIDATIONS
Definition: xact.h:154
#define RelCacheMsgs
Definition: inval.c:148
#define CatCacheMsgs
Definition: inval.c:147
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
Definition: inval.c:358
#define MinSizeOfXactInvals
Definition: xact.h:257
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:340
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:434
#define NumMessagesInGroup(group)
Definition: inval.c:183
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214
void XLogBeginInsert(void)
Definition: xloginsert.c:135
int nmsgs
Definition: xact.h:254

◆ PostPrepare_Inval()

void PostPrepare_Inval ( void  )

Definition at line 844 of file inval.c.

References AtEOXact_Inval().

Referenced by PrepareTransaction().

845 {
846  AtEOXact_Inval(false);
847 }
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1007

◆ PrepareInvalidationState()

static void PrepareInvalidationState ( void  )
static

Definition at line 774 of file inval.c.

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

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

775 {
776  TransInvalidationInfo *myInfo;
777 
778  if (transInvalInfo != NULL &&
780  return;
781 
782  myInfo = (TransInvalidationInfo *)
784  sizeof(TransInvalidationInfo));
785  myInfo->parent = transInvalInfo;
787 
788  /* Now, do we have a previous stack entry? */
789  if (transInvalInfo != NULL)
790  {
791  /* Yes; this one should be for a deeper nesting level. */
793 
794  /*
795  * The parent (sub)transaction must not have any current (i.e.,
796  * not-yet-locally-processed) messages. If it did, we'd have a
797  * semantic problem: the new subtransaction presumably ought not be
798  * able to see those events yet, but since the CommandCounter is
799  * linear, that can't work once the subtransaction advances the
800  * counter. This is a convenient place to check for that, as well as
801  * being important to keep management of the message arrays simple.
802  */
804  elog(ERROR, "cannot start a subtransaction when there are unprocessed inval messages");
805 
806  /*
807  * MemoryContextAllocZero set firstmsg = nextmsg = 0 in each group,
808  * which is fine for the first (sub)transaction, but otherwise we need
809  * to update them to follow whatever is already in the arrays.
810  */
814  &myInfo->PriorCmdInvalidMsgs);
815  }
816  else
817  {
818  /*
819  * Here, we need only clear any array pointers left over from a prior
820  * transaction.
821  */
826  }
827 
828  transInvalInfo = myInfo;
829 }
MemoryContext TopTransactionContext
Definition: mcxt.c:53
#define RelCacheMsgs
Definition: inval.c:148
#define CatCacheMsgs
Definition: inval.c:147
struct TransInvalidationInfo * parent
Definition: inval.c:208
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
SharedInvalidationMessage * msgs
Definition: inval.c:153
#define ERROR
Definition: elog.h:46
static InvalMessageArray InvalMessageArrays[2]
Definition: inval.c:157
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:906
#define NumMessagesInGroup(group)
Definition: inval.c:183
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:857
#define Assert(condition)
Definition: c.h:804
#define SetGroupToFollow(targetgroup, priorgroup)
Definition: inval.c:174
InvalidationMsgsGroup PriorCmdInvalidMsgs
Definition: inval.c:217
#define elog(elevel,...)
Definition: elog.h:232
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214

◆ ProcessCommittedInvalidationMessages()

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

Definition at line 942 of file inval.c.

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

Referenced by standby_redo(), and xact_redo_commit().

945 {
946  if (nmsgs <= 0)
947  return;
948 
949  elog(trace_recovery(DEBUG4), "replaying commit with %d messages%s", nmsgs,
950  (RelcacheInitFileInval ? " and relcache file invalidation" : ""));
951 
952  if (RelcacheInitFileInval)
953  {
954  elog(trace_recovery(DEBUG4), "removing relcache init files for database %u",
955  dbid);
956 
957  /*
958  * RelationCacheInitFilePreInvalidate, when the invalidation message
959  * is for a specific database, requires DatabasePath to be set, but we
960  * should not use SetDatabasePath during recovery, since it is
961  * intended to be used only once by normal backends. Hence, a quick
962  * hack: set DatabasePath directly then unset after use.
963  */
964  if (OidIsValid(dbid))
965  DatabasePath = GetDatabasePath(dbid, tsid);
966 
968 
969  if (OidIsValid(dbid))
970  {
972  DatabasePath = NULL;
973  }
974  }
975 
976  SendSharedInvalidMessages(msgs, nmsgs);
977 
978  if (RelcacheInitFileInval)
980 }
#define DEBUG4
Definition: elog.h:22
#define OidIsValid(objectId)
Definition: c.h:710
int trace_recovery(int trace_level)
Definition: elog.c:3597
void pfree(void *pointer)
Definition: mcxt.c:1169
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:110
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6465
char * DatabasePath
Definition: globals.c:96
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6440
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:49
#define elog(elevel,...)
Definition: elog.h:232

◆ ProcessInvalidationMessages()

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

Definition at line 500 of file inval.c.

References CatCacheMsgs, ProcessMessageSubGroup, and RelCacheMsgs.

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

502 {
503  ProcessMessageSubGroup(group, CatCacheMsgs, func(msg));
504  ProcessMessageSubGroup(group, RelCacheMsgs, func(msg));
505 }
#define RelCacheMsgs
Definition: inval.c:148
#define CatCacheMsgs
Definition: inval.c:147
#define ProcessMessageSubGroup(group, subgroup, codeFragment)
Definition: inval.c:340

◆ ProcessInvalidationMessagesMulti()

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

Definition at line 512 of file inval.c.

References CatCacheMsgs, ProcessMessageSubGroupMulti, and RelCacheMsgs.

Referenced by AtEOXact_Inval().

514 {
515  ProcessMessageSubGroupMulti(group, CatCacheMsgs, func(msgs, n));
516  ProcessMessageSubGroupMulti(group, RelCacheMsgs, func(msgs, n));
517 }
#define RelCacheMsgs
Definition: inval.c:148
#define CatCacheMsgs
Definition: inval.c:147
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
Definition: inval.c:358

◆ RegisterCatalogInvalidation()

static void RegisterCatalogInvalidation ( Oid  dbId,
Oid  catId 
)
static

Definition at line 544 of file inval.c.

References AddCatalogInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateCatalog().

545 {
547  dbId, catId);
548 }
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
static void AddCatalogInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid catId)
Definition: inval.c:409
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214

◆ RegisterCatcacheInvalidation()

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

Definition at line 530 of file inval.c.

References AddCatcacheInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateHeapTuple().

533 {
535  cacheId, hashValue, dbId);
536 }
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
static void AddCatcacheInvalidationMessage(InvalidationMsgsGroup *group, int id, uint32 hashValue, Oid dbId)
Definition: inval.c:381
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214

◆ RegisterRelcacheInvalidation()

static void RegisterRelcacheInvalidation ( Oid  dbId,
Oid  relId 
)
static

Definition at line 556 of file inval.c.

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

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

557 {
559  dbId, relId);
560 
561  /*
562  * Most of the time, relcache invalidation is associated with system
563  * catalog updates, but there are a few cases where it isn't. Quick hack
564  * to ensure that the next CommandCounterIncrement() will think that we
565  * need to do CommandEndInvalidationMessages().
566  */
567  (void) GetCurrentCommandId(true);
568 
569  /*
570  * If the relation being invalidated is one of those cached in a relcache
571  * init file, mark that we need to zap that file at commit. For simplicity
572  * invalidations for a specific database always invalidate the shared file
573  * as well. Also zap when we are invalidating whole relcache.
574  */
575  if (relId == InvalidOid || RelationIdIsInInitFile(relId))
577 }
bool RelationIdIsInInitFile(Oid relationId)
Definition: relcache.c:6400
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
bool RelcacheInitFileInval
Definition: inval.c:220
#define InvalidOid
Definition: postgres_ext.h:36
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214
static void AddRelcacheInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid relId)
Definition: inval.c:427
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:761

◆ RegisterSnapshotInvalidation()

static void RegisterSnapshotInvalidation ( Oid  dbId,
Oid  relId 
)
static

Definition at line 586 of file inval.c.

References AddSnapshotInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateHeapTuple().

587 {
589  dbId, relId);
590 }
static void AddSnapshotInvalidationMessage(InvalidationMsgsGroup *group, Oid dbId, Oid relId)
Definition: inval.c:459
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214

◆ xactGetCommittedInvalidationMessages()

int xactGetCommittedInvalidationMessages ( SharedInvalidationMessage **  msgs,
bool RelcacheInitFileInval 
)

Definition at line 863 of file inval.c.

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

Referenced by RecordTransactionCommit(), and StartPrepare().

865 {
866  SharedInvalidationMessage *msgarray;
867  int nummsgs;
868  int nmsgs;
869 
870  /* Quick exit if we haven't done anything with invalidation messages. */
871  if (transInvalInfo == NULL)
872  {
873  *RelcacheInitFileInval = false;
874  *msgs = NULL;
875  return 0;
876  }
877 
878  /* Must be at top of stack */
880 
881  /*
882  * Relcache init file invalidation requires processing both before and
883  * after we send the SI messages. However, we need not do anything unless
884  * we committed.
885  */
886  *RelcacheInitFileInval = transInvalInfo->RelcacheInitFileInval;
887 
888  /*
889  * Collect all the pending messages into a single contiguous array of
890  * invalidation messages, to simplify what needs to happen while building
891  * the commit WAL message. Maintain the order that they would be
892  * processed in by AtEOXact_Inval(), to ensure emulated behaviour in redo
893  * is as similar as possible to original. We want the same bugs, if any,
894  * not new ones.
895  */
898 
899  *msgs = msgarray = (SharedInvalidationMessage *)
901  nummsgs * sizeof(SharedInvalidationMessage));
902 
903  nmsgs = 0;
905  CatCacheMsgs,
906  (memcpy(msgarray + nmsgs,
907  msgs,
908  n * sizeof(SharedInvalidationMessage)),
909  nmsgs += n));
911  CatCacheMsgs,
912  (memcpy(msgarray + nmsgs,
913  msgs,
914  n * sizeof(SharedInvalidationMessage)),
915  nmsgs += n));
917  RelCacheMsgs,
918  (memcpy(msgarray + nmsgs,
919  msgs,
920  n * sizeof(SharedInvalidationMessage)),
921  nmsgs += n));
923  RelCacheMsgs,
924  (memcpy(msgarray + nmsgs,
925  msgs,
926  n * sizeof(SharedInvalidationMessage)),
927  nmsgs += n));
928  Assert(nmsgs == nummsgs);
929 
930  return nmsgs;
931 }
#define RelCacheMsgs
Definition: inval.c:148
#define CatCacheMsgs
Definition: inval.c:147
MemoryContext CurTransactionContext
Definition: mcxt.c:54
struct TransInvalidationInfo * parent
Definition: inval.c:208
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:223
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
Definition: inval.c:358
bool RelcacheInitFileInval
Definition: inval.c:220
#define NumMessagesInGroup(group)
Definition: inval.c:183
#define Assert(condition)
Definition: c.h:804
InvalidationMsgsGroup PriorCmdInvalidMsgs
Definition: inval.c:217
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:214

Variable Documentation

◆ debug_discard_caches

int debug_discard_caches = 0

Definition at line 226 of file inval.c.

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

◆ InvalMessageArrays

InvalMessageArray InvalMessageArrays[2]
static

Definition at line 157 of file inval.c.

◆ relcache_callback_count

int relcache_callback_count = 0
static

◆ relcache_callback_list

◆ syscache_callback_count

int syscache_callback_count = 0
static

Definition at line 251 of file inval.c.

Referenced by CacheRegisterSyscacheCallback(), and InvalidateSystemCaches().

◆ syscache_callback_links

int16 syscache_callback_links[SysCacheSize]
static

Definition at line 249 of file inval.c.

Referenced by CacheRegisterSyscacheCallback(), and CallSyscacheCallbacks().

◆ syscache_callback_list

◆ transInvalInfo

TransInvalidationInfo* transInvalInfo = NULL
static

Definition at line 223 of file inval.c.

Referenced by AtEOSubXact_Inval(), and PrepareInvalidationState().