PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
inval.c File Reference
#include "postgres.h"
#include <limits.h>
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "miscadmin.h"
#include "storage/sinval.h"
#include "storage/smgr.h"
#include "utils/catcache.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  InvalidationChunk
 
struct  InvalidationListHeader
 
struct  TransInvalidationInfo
 
struct  SYSCACHECALLBACK
 
struct  RELCACHECALLBACK
 

Macros

#define MAX_SYSCACHE_CALLBACKS   64
 
#define MAX_RELCACHE_CALLBACKS   10
 
#define FIRSTCHUNKSIZE   32
 
#define ProcessMessageList(listHdr, codeFragment)
 
#define ProcessMessageListMulti(listHdr, codeFragment)
 

Typedefs

typedef struct InvalidationChunk InvalidationChunk
 
typedef struct
InvalidationListHeader 
InvalidationListHeader
 
typedef struct
TransInvalidationInfo 
TransInvalidationInfo
 

Functions

static void AddInvalidationMessage (InvalidationChunk **listHdr, SharedInvalidationMessage *msg)
 
static void AppendInvalidationMessageList (InvalidationChunk **destHdr, InvalidationChunk **srcHdr)
 
static void AddCatcacheInvalidationMessage (InvalidationListHeader *hdr, int id, uint32 hashValue, Oid dbId)
 
static void AddCatalogInvalidationMessage (InvalidationListHeader *hdr, Oid dbId, Oid catId)
 
static void AddRelcacheInvalidationMessage (InvalidationListHeader *hdr, Oid dbId, Oid relId)
 
static void AddSnapshotInvalidationMessage (InvalidationListHeader *hdr, Oid dbId, Oid relId)
 
static void AppendInvalidationMessages (InvalidationListHeader *dest, InvalidationListHeader *src)
 
static void ProcessInvalidationMessages (InvalidationListHeader *hdr, void(*func)(SharedInvalidationMessage *msg))
 
static void ProcessInvalidationMessagesMulti (InvalidationListHeader *hdr, 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)
 
static void MakeSharedInvalidMessagesArray (const SharedInvalidationMessage *msgs, int n)
 
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)
 

Variables

static TransInvalidationInfotransInvalInfo = NULL
 
static SharedInvalidationMessageSharedInvalidMessagesArray
 
static int numSharedInvalidMessagesArray
 
static int maxSharedInvalidMessagesArray
 
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

#define FIRSTCHUNKSIZE   32
#define MAX_RELCACHE_CALLBACKS   10

Definition at line 189 of file inval.c.

Referenced by CacheRegisterRelcacheCallback().

#define MAX_SYSCACHE_CALLBACKS   64

Definition at line 188 of file inval.c.

Referenced by CacheRegisterSyscacheCallback().

#define ProcessMessageList (   listHdr,
  codeFragment 
)
Value:
do { \
for (_chunk = (listHdr); _chunk != NULL; _chunk = _chunk->next) \
{ \
int _cindex; \
for (_cindex = 0; _cindex < _chunk->nitems; _cindex++) \
{ \
SharedInvalidationMessage *msg = &_chunk->msgs[_cindex]; \
codeFragment; \
} \
} \
} while (0)
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
Definition: inval.c:127
struct InvalidationChunk InvalidationChunk
#define NULL
Definition: c.h:229

Definition at line 293 of file inval.c.

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

#define ProcessMessageListMulti (   listHdr,
  codeFragment 
)
Value:
do { \
for (_chunk = (listHdr); _chunk != NULL; _chunk = _chunk->next) \
{ \
SharedInvalidationMessage *msgs = _chunk->msgs; \
int n = _chunk->nitems; \
codeFragment; \
} \
} while (0)
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
Definition: inval.c:127
struct InvalidationChunk InvalidationChunk
#define NULL
Definition: c.h:229

Definition at line 313 of file inval.c.

Referenced by ProcessInvalidationMessagesMulti().

Typedef Documentation

Function Documentation

void AcceptInvalidationMessages ( void  )

Definition at line 679 of file inval.c.

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

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

680 {
683 
684  /*
685  * Test code to force cache flushes anytime a flush could happen.
686  *
687  * If used with CLOBBER_FREED_MEMORY, CLOBBER_CACHE_ALWAYS provides a
688  * fairly thorough test that the system contains no cache-flush hazards.
689  * However, it also makes the system unbelievably slow --- the regression
690  * tests take about 100 times longer than normal.
691  *
692  * If you're a glutton for punishment, try CLOBBER_CACHE_RECURSIVELY. This
693  * slows things by at least a factor of 10000, so I wouldn't suggest
694  * trying to run the entire regression tests that way. It's useful to try
695  * a few simple tests, to make sure that cache reload isn't subject to
696  * internal cache-flush hazards, but after you've done a few thousand
697  * recursive reloads it's unlikely you'll learn more.
698  */
699 #if defined(CLOBBER_CACHE_ALWAYS)
700  {
701  static bool in_recursion = false;
702 
703  if (!in_recursion)
704  {
705  in_recursion = true;
707  in_recursion = false;
708  }
709  }
710 #elif defined(CLOBBER_CACHE_RECURSIVELY)
712 #endif
713 }
void InvalidateSystemCaches(void)
Definition: inval.c:641
void ReceiveSharedInvalidMessages(void(*invalFunction)(SharedInvalidationMessage *msg), void(*resetFunction)(void))
Definition: sinval.c:71
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:554
static void AddCatalogInvalidationMessage ( InvalidationListHeader hdr,
Oid  dbId,
Oid  catId 
)
static

Definition at line 365 of file inval.c.

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

Referenced by RegisterCatalogInvalidation().

367 {
369 
371  msg.cat.dbId = dbId;
372  msg.cat.catId = catId;
373  /* check AddCatcacheInvalidationMessage() for an explanation */
374  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
375 
376  AddInvalidationMessage(&hdr->cclist, &msg);
377 }
static void AddInvalidationMessage(InvalidationChunk **listHdr, SharedInvalidationMessage *msg)
Definition: inval.c:227
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
InvalidationChunk * cclist
Definition: inval.c:132
SharedInvalCatalogMsg cat
Definition: sinval.h:117
#define SHAREDINVALCATALOG_ID
Definition: sinval.h:67
static void AddCatcacheInvalidationMessage ( InvalidationListHeader hdr,
int  id,
uint32  hashValue,
Oid  dbId 
)
static

Definition at line 337 of file inval.c.

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

Referenced by RegisterCatcacheInvalidation().

339 {
341 
342  Assert(id < CHAR_MAX);
343  msg.cc.id = (int8) id;
344  msg.cc.dbId = dbId;
345  msg.cc.hashValue = hashValue;
346 
347  /*
348  * Define padding bytes in SharedInvalidationMessage structs to be
349  * defined. Otherwise the sinvaladt.c ringbuffer, which is accessed by
350  * multiple processes, will cause spurious valgrind warnings about
351  * undefined memory being used. That's because valgrind remembers the
352  * undefined bytes from the last local process's store, not realizing that
353  * another process has written since, filling the previously uninitialized
354  * bytes
355  */
356  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
357 
358  AddInvalidationMessage(&hdr->cclist, &msg);
359 }
static void AddInvalidationMessage(InvalidationChunk **listHdr, SharedInvalidationMessage *msg)
Definition: inval.c:227
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
InvalidationChunk * cclist
Definition: inval.c:132
SharedInvalCatcacheMsg cc
Definition: sinval.h:116
signed char int8
Definition: c.h:254
#define Assert(condition)
Definition: c.h:676
static void AddInvalidationMessage ( InvalidationChunk **  listHdr,
SharedInvalidationMessage msg 
)
static

Definition at line 227 of file inval.c.

References CurTransactionContext, FIRSTCHUNKSIZE, InvalidationChunk::maxitems, MemoryContextAlloc(), InvalidationChunk::msgs, InvalidationChunk::next, InvalidationChunk::nitems, NULL, and offsetof.

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

229 {
230  InvalidationChunk *chunk = *listHdr;
231 
232  if (chunk == NULL)
233  {
234  /* First time through; create initial chunk */
235 #define FIRSTCHUNKSIZE 32
236  chunk = (InvalidationChunk *)
238  offsetof(InvalidationChunk, msgs) +
240  chunk->nitems = 0;
241  chunk->maxitems = FIRSTCHUNKSIZE;
242  chunk->next = *listHdr;
243  *listHdr = chunk;
244  }
245  else if (chunk->nitems >= chunk->maxitems)
246  {
247  /* Need another chunk; double size of last chunk */
248  int chunksize = 2 * chunk->maxitems;
249 
250  chunk = (InvalidationChunk *)
252  offsetof(InvalidationChunk, msgs) +
253  chunksize * sizeof(SharedInvalidationMessage));
254  chunk->nitems = 0;
255  chunk->maxitems = chunksize;
256  chunk->next = *listHdr;
257  *listHdr = chunk;
258  }
259  /* Okay, add message to current chunk */
260  chunk->msgs[chunk->nitems] = *msg;
261  chunk->nitems++;
262 }
#define FIRSTCHUNKSIZE
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
Definition: inval.c:127
MemoryContext CurTransactionContext
Definition: mcxt.c:49
struct InvalidationChunk * next
Definition: inval.c:124
#define NULL
Definition: c.h:229
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:707
#define offsetof(type, field)
Definition: c.h:555
static void AddRelcacheInvalidationMessage ( InvalidationListHeader hdr,
Oid  dbId,
Oid  relId 
)
static

Definition at line 383 of file inval.c.

References AddInvalidationMessage(), SharedInvalRelcacheMsg::dbId, SharedInvalRelcacheMsg::id, InvalidOid, ProcessMessageList, SharedInvalidationMessage::rc, InvalidationListHeader::rclist, SharedInvalRelcacheMsg::relId, SHAREDINVALRELCACHE_ID, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by RegisterRelcacheInvalidation().

385 {
387 
388  /*
389  * Don't add a duplicate item. We assume dbId need not be checked because
390  * it will never change. InvalidOid for relId means all relations so we
391  * don't need to add individual ones when it is present.
392  */
394  if (msg->rc.id == SHAREDINVALRELCACHE_ID &&
395  (msg->rc.relId == relId ||
396  msg->rc.relId == InvalidOid))
397  return);
398 
399  /* OK, add the item */
401  msg.rc.dbId = dbId;
402  msg.rc.relId = relId;
403  /* check AddCatcacheInvalidationMessage() for an explanation */
404  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
405 
406  AddInvalidationMessage(&hdr->rclist, &msg);
407 }
static void AddInvalidationMessage(InvalidationChunk **listHdr, SharedInvalidationMessage *msg)
Definition: inval.c:227
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
SharedInvalRelcacheMsg rc
Definition: sinval.h:118
#define ProcessMessageList(listHdr, codeFragment)
Definition: inval.c:293
#define SHAREDINVALRELCACHE_ID
Definition: sinval.h:76
#define InvalidOid
Definition: postgres_ext.h:36
InvalidationChunk * rclist
Definition: inval.c:133
static void AddSnapshotInvalidationMessage ( InvalidationListHeader hdr,
Oid  dbId,
Oid  relId 
)
static

Definition at line 413 of file inval.c.

References AddInvalidationMessage(), SharedInvalSnapshotMsg::dbId, SharedInvalSnapshotMsg::id, ProcessMessageList, InvalidationListHeader::rclist, SharedInvalSnapshotMsg::relId, SHAREDINVALSNAPSHOT_ID, SharedInvalidationMessage::sn, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by RegisterSnapshotInvalidation().

415 {
417 
418  /* Don't add a duplicate item */
419  /* We assume dbId need not be checked because it will never change */
421  if (msg->sn.id == SHAREDINVALSNAPSHOT_ID &&
422  msg->sn.relId == relId)
423  return);
424 
425  /* OK, add the item */
427  msg.sn.dbId = dbId;
428  msg.sn.relId = relId;
429  /* check AddCatcacheInvalidationMessage() for an explanation */
430  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
431 
432  AddInvalidationMessage(&hdr->rclist, &msg);
433 }
SharedInvalSnapshotMsg sn
Definition: sinval.h:121
static void AddInvalidationMessage(InvalidationChunk **listHdr, SharedInvalidationMessage *msg)
Definition: inval.c:227
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
#define ProcessMessageList(listHdr, codeFragment)
Definition: inval.c:293
#define SHAREDINVALSNAPSHOT_ID
Definition: sinval.h:104
InvalidationChunk * rclist
Definition: inval.c:133
static void AppendInvalidationMessageList ( InvalidationChunk **  destHdr,
InvalidationChunk **  srcHdr 
)
static

Definition at line 269 of file inval.c.

References InvalidationChunk::next, and NULL.

Referenced by AppendInvalidationMessages().

271 {
272  InvalidationChunk *chunk = *srcHdr;
273 
274  if (chunk == NULL)
275  return; /* nothing to do */
276 
277  while (chunk->next != NULL)
278  chunk = chunk->next;
279 
280  chunk->next = *destHdr;
281 
282  *destHdr = *srcHdr;
283 
284  *srcHdr = NULL;
285 }
struct InvalidationChunk * next
Definition: inval.c:124
#define NULL
Definition: c.h:229
static void AppendInvalidationMessages ( InvalidationListHeader dest,
InvalidationListHeader src 
)
static

Definition at line 440 of file inval.c.

References AppendInvalidationMessageList(), InvalidationListHeader::cclist, and InvalidationListHeader::rclist.

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

442 {
445 }
InvalidationChunk * cclist
Definition: inval.c:132
InvalidationChunk * rclist
Definition: inval.c:133
static void AppendInvalidationMessageList(InvalidationChunk **destHdr, InvalidationChunk **srcHdr)
Definition: inval.c:269
void AtEOSubXact_Inval ( bool  isCommit)

Definition at line 988 of file inval.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

989 {
990  int my_level;
992 
993  /* Quick exit if no messages. */
994  if (myInfo == NULL)
995  return;
996 
997  /* Also bail out quickly if messages are not for this level. */
998  my_level = GetCurrentTransactionNestLevel();
999  if (myInfo->my_level != my_level)
1000  {
1001  Assert(myInfo->my_level < my_level);
1002  return;
1003  }
1004 
1005  if (isCommit)
1006  {
1007  /* If CurrentCmdInvalidMsgs still has anything, fix it */
1009 
1010  /*
1011  * We create invalidation stack entries lazily, so the parent might
1012  * not have one. Instead of creating one, moving all the data over,
1013  * and then freeing our own, we can just adjust the level of our own
1014  * entry.
1015  */
1016  if (myInfo->parent == NULL || myInfo->parent->my_level < my_level - 1)
1017  {
1018  myInfo->my_level--;
1019  return;
1020  }
1021 
1022  /* Pass up my inval messages to parent */
1024  &myInfo->PriorCmdInvalidMsgs);
1025 
1026  /* Pending relcache inval becomes parent's problem too */
1027  if (myInfo->RelcacheInitFileInval)
1028  myInfo->parent->RelcacheInitFileInval = true;
1029 
1030  /* Pop the transaction state stack */
1031  transInvalInfo = myInfo->parent;
1032 
1033  /* Need not free anything else explicitly */
1034  pfree(myInfo);
1035  }
1036  else
1037  {
1040 
1041  /* Pop the transaction state stack */
1042  transInvalInfo = myInfo->parent;
1043 
1044  /* Need not free anything else explicitly */
1045  pfree(myInfo);
1046  }
1047 }
static void AppendInvalidationMessages(InvalidationListHeader *dest, InvalidationListHeader *src)
Definition: inval.c:440
InvalidationListHeader PriorCmdInvalidMsgs
Definition: inval.c:165
void CommandEndInvalidationMessages(void)
Definition: inval.c:1065
struct TransInvalidationInfo * parent
Definition: inval.c:156
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
void pfree(void *pointer)
Definition: mcxt.c:950
bool RelcacheInitFileInval
Definition: inval.c:168
static void ProcessInvalidationMessages(InvalidationListHeader *hdr, void(*func)(SharedInvalidationMessage *msg))
Definition: inval.c:454
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:761
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:554
void AtEOXact_Inval ( bool  isCommit)

Definition at line 929 of file inval.c.

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

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

930 {
931  /* Quick exit if no messages */
932  if (transInvalInfo == NULL)
933  return;
934 
935  /* Must be at top of stack */
937 
938  if (isCommit)
939  {
940  /*
941  * Relcache init file invalidation requires processing both before and
942  * after we send the SI messages. However, we need not do anything
943  * unless we committed.
944  */
947 
950 
953 
956  }
957  else
958  {
961  }
962 
963  /* Need not free anything explicitly */
967 }
static void AppendInvalidationMessages(InvalidationListHeader *dest, InvalidationListHeader *src)
Definition: inval.c:440
static SharedInvalidationMessage * SharedInvalidMessagesArray
Definition: inval.c:173
InvalidationListHeader PriorCmdInvalidMsgs
Definition: inval.c:165
struct TransInvalidationInfo * parent
Definition: inval.c:156
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
InvalidationListHeader CurrentCmdInvalidMsgs
Definition: inval.c:162
static int numSharedInvalidMessagesArray
Definition: inval.c:174
static void ProcessInvalidationMessagesMulti(InvalidationListHeader *hdr, void(*func)(const SharedInvalidationMessage *msgs, int n))
Definition: inval.c:466
bool RelcacheInitFileInval
Definition: inval.c:168
static void ProcessInvalidationMessages(InvalidationListHeader *hdr, void(*func)(SharedInvalidationMessage *msg))
Definition: inval.c:454
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6084
#define NULL
Definition: c.h:229
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6058
#define Assert(condition)
Definition: c.h:676
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:49
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:554
void CacheInvalidateCatalog ( Oid  catalogId)

Definition at line 1209 of file inval.c.

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

Referenced by finish_heap_swap().

1210 {
1211  Oid databaseId;
1212 
1214 
1215  if (IsSharedRelation(catalogId))
1216  databaseId = InvalidOid;
1217  else
1218  databaseId = MyDatabaseId;
1219 
1220  RegisterCatalogInvalidation(databaseId, catalogId);
1221 }
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:720
Oid MyDatabaseId
Definition: globals.c:77
static void RegisterCatalogInvalidation(Oid dbId, Oid catId)
Definition: inval.c:498
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:220
#define InvalidOid
Definition: postgres_ext.h:36
void CacheInvalidateHeapTuple ( Relation  relation,
HeapTuple  tuple,
HeapTuple  newtuple 
)

Definition at line 1094 of file inval.c.

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

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

1097 {
1098  Oid tupleRelId;
1099  Oid databaseId;
1100  Oid relationId;
1101 
1102  /* Do nothing during bootstrap */
1104  return;
1105 
1106  /*
1107  * We only need to worry about invalidation for tuples that are in system
1108  * catalogs; user-relation tuples are never in catcaches and can't affect
1109  * the relcache either.
1110  */
1111  if (!IsCatalogRelation(relation))
1112  return;
1113 
1114  /*
1115  * IsCatalogRelation() will return true for TOAST tables of system
1116  * catalogs, but we don't care about those, either.
1117  */
1118  if (IsToastRelation(relation))
1119  return;
1120 
1121  /*
1122  * If we're not prepared to queue invalidation messages for this
1123  * subtransaction level, get ready now.
1124  */
1126 
1127  /*
1128  * First let the catcache do its thing
1129  */
1130  tupleRelId = RelationGetRelid(relation);
1131  if (RelationInvalidatesSnapshotsOnly(tupleRelId))
1132  {
1133  databaseId = IsSharedRelation(tupleRelId) ? InvalidOid : MyDatabaseId;
1134  RegisterSnapshotInvalidation(databaseId, tupleRelId);
1135  }
1136  else
1137  PrepareToInvalidateCacheTuple(relation, tuple, newtuple,
1139 
1140  /*
1141  * Now, is this tuple one of the primary definers of a relcache entry? See
1142  * comments in file header for deeper explanation.
1143  *
1144  * Note we ignore newtuple here; we assume an update cannot move a tuple
1145  * from being part of one relcache entry to being part of another.
1146  */
1147  if (tupleRelId == RelationRelationId)
1148  {
1149  Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple);
1150 
1151  relationId = HeapTupleGetOid(tuple);
1152  if (classtup->relisshared)
1153  databaseId = InvalidOid;
1154  else
1155  databaseId = MyDatabaseId;
1156  }
1157  else if (tupleRelId == AttributeRelationId)
1158  {
1159  Form_pg_attribute atttup = (Form_pg_attribute) GETSTRUCT(tuple);
1160 
1161  relationId = atttup->attrelid;
1162 
1163  /*
1164  * KLUGE ALERT: we always send the relcache event with MyDatabaseId,
1165  * even if the rel in question is shared (which we can't easily tell).
1166  * This essentially means that only backends in this same database
1167  * will react to the relcache flush request. This is in fact
1168  * appropriate, since only those backends could see our pg_attribute
1169  * change anyway. It looks a bit ugly though. (In practice, shared
1170  * relations can't have schema changes after bootstrap, so we should
1171  * never come here for a shared rel anyway.)
1172  */
1173  databaseId = MyDatabaseId;
1174  }
1175  else if (tupleRelId == IndexRelationId)
1176  {
1177  Form_pg_index indextup = (Form_pg_index) GETSTRUCT(tuple);
1178 
1179  /*
1180  * When a pg_index row is updated, we should send out a relcache inval
1181  * for the index relation. As above, we don't know the shared status
1182  * of the index, but in practice it doesn't matter since indexes of
1183  * shared catalogs can't have such updates.
1184  */
1185  relationId = indextup->indexrelid;
1186  databaseId = MyDatabaseId;
1187  }
1188  else
1189  return;
1190 
1191  /*
1192  * Yes. We need to register a relcache invalidation event.
1193  */
1194  RegisterRelcacheInvalidation(databaseId, relationId);
1195 }
bool IsToastRelation(Relation relation)
Definition: catalog.c:136
bool IsCatalogRelation(Relation relation)
Definition: catalog.c:92
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define IndexRelationId
Definition: pg_index.h:29
#define RelationRelationId
Definition: pg_class.h:29
void PrepareToInvalidateCacheTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid))
Definition: catcache.c:1782
#define AttributeRelationId
Definition: pg_attribute.h:33
unsigned int Oid
Definition: postgres_ext.h:31
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
static void PrepareInvalidationState(void)
Definition: inval.c:720
FormData_pg_index * Form_pg_index
Definition: pg_index.h:67
Oid MyDatabaseId
Definition: globals.c:77
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:220
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:510
static void RegisterCatcacheInvalidation(int cacheId, uint32 hashValue, Oid dbId)
Definition: inval.c:484
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition: syscache.c:1375
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:368
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
#define RelationGetRelid(relation)
Definition: rel.h:416
static void RegisterSnapshotInvalidation(Oid dbId, Oid relId)
Definition: inval.c:540
void CacheInvalidateRelcache ( Relation  relation)

Definition at line 1233 of file inval.c.

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

Referenced by AlterPolicy(), ATExecAlterConstraint(), ATExecDetachPartition(), ATExecGenericOptions(), ATExecValidateConstraint(), CreatePolicy(), CreateStatistics(), EnableDisableRule(), EnableDisableTrigger(), index_drop(), publication_add_relation(), reindex_index(), RemovePolicyById(), RemoveRewriteRuleById(), RemoveRoleFromObjectPolicy(), RemoveTriggerById(), rename_policy(), RenameRewriteRule(), renametrig(), SetRelationNumChecks(), StorePartitionBound(), and StorePartitionKey().

1234 {
1235  Oid databaseId;
1236  Oid relationId;
1237 
1239 
1240  relationId = RelationGetRelid(relation);
1241  if (relation->rd_rel->relisshared)
1242  databaseId = InvalidOid;
1243  else
1244  databaseId = MyDatabaseId;
1245 
1246  RegisterRelcacheInvalidation(databaseId, relationId);
1247 }
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:720
Oid MyDatabaseId
Definition: globals.c:77
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:510
#define RelationGetRelid(relation)
Definition: rel.h:416
void CacheInvalidateRelcacheAll ( void  )

Definition at line 1257 of file inval.c.

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

Referenced by AlterPublicationOptions().

1258 {
1260 
1262 }
static void PrepareInvalidationState(void)
Definition: inval.c:720
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:510
void CacheInvalidateRelcacheByRelid ( Oid  relid)

Definition at line 1292 of file inval.c.

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

Referenced by AlterPublicationOptions(), ATExecAlterConstraint(), DefineIndex(), heap_drop_with_catalog(), RemovePublicationRelById(), and RemoveStatisticsById().

1293 {
1294  HeapTuple tup;
1295 
1297 
1298  tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1299  if (!HeapTupleIsValid(tup))
1300  elog(ERROR, "cache lookup failed for relation %u", relid);
1302  ReleaseSysCache(tup);
1303 }
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
static void PrepareInvalidationState(void)
Definition: inval.c:720
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
Definition: inval.c:1269
#define elog
Definition: elog.h:219
void CacheInvalidateRelcacheByTuple ( HeapTuple  classTuple)

Definition at line 1269 of file inval.c.

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

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

1270 {
1271  Form_pg_class classtup = (Form_pg_class) GETSTRUCT(classTuple);
1272  Oid databaseId;
1273  Oid relationId;
1274 
1276 
1277  relationId = HeapTupleGetOid(classTuple);
1278  if (classtup->relisshared)
1279  databaseId = InvalidOid;
1280  else
1281  databaseId = MyDatabaseId;
1282  RegisterRelcacheInvalidation(databaseId, relationId);
1283 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:720
Oid MyDatabaseId
Definition: globals.c:77
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:510
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
void CacheInvalidateRelmap ( Oid  databaseId)

Definition at line 1362 of file inval.c.

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

Referenced by write_relmap_file().

1363 {
1365 
1366  msg.rm.id = SHAREDINVALRELMAP_ID;
1367  msg.rm.dbId = databaseId;
1368  /* check AddCatcacheInvalidationMessage() for an explanation */
1369  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1370 
1371  SendSharedInvalidMessages(&msg, 1);
1372 }
#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
void CacheInvalidateSmgr ( RelFileNodeBackend  rnode)

Definition at line 1332 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 smgrdounlink(), smgrdounlinkall(), smgrdounlinkfork(), smgrtruncate(), and vm_extend().

1333 {
1335 
1336  msg.sm.id = SHAREDINVALSMGR_ID;
1337  msg.sm.backend_hi = rnode.backend >> 16;
1338  msg.sm.backend_lo = rnode.backend & 0xffff;
1339  msg.sm.rnode = rnode.node;
1340  /* check AddCatcacheInvalidationMessage() for an explanation */
1341  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1342 
1343  SendSharedInvalidMessages(&msg, 1);
1344 }
#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
void CacheRegisterRelcacheCallback ( RelcacheCallbackFunction  func,
Datum  arg 
)

Definition at line 1431 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_relmap_init(), and lookup_type_cache().

1433 {
1435  elog(FATAL, "out of relcache_callback_list slots");
1436 
1439 
1441 }
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
#define MAX_RELCACHE_CALLBACKS
Definition: inval.c:189
static int relcache_callback_count
Definition: inval.c:209
RelcacheCallbackFunction function
Definition: inval.c:205
#define FATAL
Definition: elog.h:52
void * arg
#define elog
Definition: elog.h:219
void CacheRegisterSyscacheCallback ( int  cacheid,
SyscacheCallbackFunction  func,
Datum  arg 
)

Definition at line 1389 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(), logicalrep_relmap_init(), lookup_proof_cache(), lookup_ts_dictionary_cache(), lookup_ts_parser_cache(), lookup_type_cache(), pgoutput_startup(), ri_InitHashTables(), and superuser_arg().

1392 {
1393  if (cacheid < 0 || cacheid >= SysCacheSize)
1394  elog(FATAL, "invalid cache ID: %d", cacheid);
1396  elog(FATAL, "out of syscache_callback_list slots");
1397 
1398  if (syscache_callback_links[cacheid] == 0)
1399  {
1400  /* first callback for this cache */
1402  }
1403  else
1404  {
1405  /* add to end of chain, so that older callbacks are called first */
1406  int i = syscache_callback_links[cacheid] - 1;
1407 
1408  while (syscache_callback_list[i].link > 0)
1409  i = syscache_callback_list[i].link - 1;
1411  }
1412 
1417 
1419 }
int16 link
Definition: inval.c:194
#define SysCacheSize
Definition: syscache.h:112
#define FATAL
Definition: elog.h:52
#define MAX_SYSCACHE_CALLBACKS
Definition: inval.c:188
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
static int syscache_callback_count
Definition: inval.c:201
static int16 syscache_callback_links[SysCacheSize]
Definition: inval.c:199
int i
void * arg
#define elog
Definition: elog.h:219
SyscacheCallbackFunction function
Definition: inval.c:195
void CallSyscacheCallbacks ( int  cacheid,
uint32  hashvalue 
)

Definition at line 1450 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().

1451 {
1452  int i;
1453 
1454  if (cacheid < 0 || cacheid >= SysCacheSize)
1455  elog(ERROR, "invalid cache ID: %d", cacheid);
1456 
1457  i = syscache_callback_links[cacheid] - 1;
1458  while (i >= 0)
1459  {
1460  struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
1461 
1462  Assert(ccitem->id == cacheid);
1463  (*ccitem->function) (ccitem->arg, cacheid, hashvalue);
1464  i = ccitem->link - 1;
1465  }
1466 }
int16 link
Definition: inval.c:194
#define SysCacheSize
Definition: syscache.h:112
#define ERROR
Definition: elog.h:43
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
#define Assert(condition)
Definition: c.h:676
static int16 syscache_callback_links[SysCacheSize]
Definition: inval.c:199
int i
#define elog
Definition: elog.h:219
SyscacheCallbackFunction function
Definition: inval.c:195
void CommandEndInvalidationMessages ( void  )

Definition at line 1065 of file inval.c.

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

Referenced by AtCCI_LocalCache(), and AtEOSubXact_Inval().

1066 {
1067  /*
1068  * You might think this shouldn't be called outside any transaction, but
1069  * bootstrap does it, and also ABORT issued when not in a transaction. So
1070  * just quietly return if no state to work on.
1071  */
1072  if (transInvalInfo == NULL)
1073  return;
1074 
1079 }
static void AppendInvalidationMessages(InvalidationListHeader *dest, InvalidationListHeader *src)
Definition: inval.c:440
InvalidationListHeader PriorCmdInvalidMsgs
Definition: inval.c:165
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
InvalidationListHeader CurrentCmdInvalidMsgs
Definition: inval.c:162
static void ProcessInvalidationMessages(InvalidationListHeader *hdr, void(*func)(SharedInvalidationMessage *msg))
Definition: inval.c:454
#define NULL
Definition: c.h:229
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:554
void InvalidateSystemCaches ( void  )

Definition at line 641 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(), and pg_logical_slot_get_changes_guts().

642 {
643  int i;
644 
647  RelationCacheInvalidate(); /* gets smgr and relmap too */
648 
649  for (i = 0; i < syscache_callback_count; i++)
650  {
651  struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
652 
653  (*ccitem->function) (ccitem->arg, ccitem->id, 0);
654  }
655 
656  for (i = 0; i < relcache_callback_count; i++)
657  {
658  struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
659 
660  (*ccitem->function) (ccitem->arg, InvalidOid);
661  }
662 }
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
static int relcache_callback_count
Definition: inval.c:209
RelcacheCallbackFunction function
Definition: inval.c:205
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:510
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
static int syscache_callback_count
Definition: inval.c:201
#define InvalidOid
Definition: postgres_ext.h:36
void ResetCatalogCaches(void)
Definition: catcache.c:580
void RelationCacheInvalidate(void)
Definition: relcache.c:2764
int i
SyscacheCallbackFunction function
Definition: inval.c:195
void LocalExecuteInvalidationMessage ( SharedInvalidationMessage msg)

Definition at line 554 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, 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(), and SysCacheInvalidate().

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

555 {
556  if (msg->id >= 0)
557  {
558  if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid)
559  {
561 
562  SysCacheInvalidate(msg->cc.id, msg->cc.hashValue);
563 
564  CallSyscacheCallbacks(msg->cc.id, msg->cc.hashValue);
565  }
566  }
567  else if (msg->id == SHAREDINVALCATALOG_ID)
568  {
569  if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid)
570  {
572 
574 
575  /* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */
576  }
577  }
578  else if (msg->id == SHAREDINVALRELCACHE_ID)
579  {
580  if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid)
581  {
582  int i;
583 
584  if (msg->rc.relId == InvalidOid)
586  else
588 
589  for (i = 0; i < relcache_callback_count; i++)
590  {
591  struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
592 
593  (*ccitem->function) (ccitem->arg, msg->rc.relId);
594  }
595  }
596  }
597  else if (msg->id == SHAREDINVALSMGR_ID)
598  {
599  /*
600  * We could have smgr entries for relations of other databases, so no
601  * short-circuit test is possible here.
602  */
603  RelFileNodeBackend rnode;
604 
605  rnode.node = msg->sm.rnode;
606  rnode.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo;
607  smgrclosenode(rnode);
608  }
609  else if (msg->id == SHAREDINVALRELMAP_ID)
610  {
611  /* We only care about our own database and shared catalogs */
612  if (msg->rm.dbId == InvalidOid)
613  RelationMapInvalidate(true);
614  else if (msg->rm.dbId == MyDatabaseId)
615  RelationMapInvalidate(false);
616  }
617  else if (msg->id == SHAREDINVALSNAPSHOT_ID)
618  {
619  /* We only care about our own database and shared catalogs */
620  if (msg->rm.dbId == InvalidOid)
622  else if (msg->rm.dbId == MyDatabaseId)
624  }
625  else
626  elog(FATAL, "unrecognized SI message ID: %d", msg->id);
627 }
SharedInvalRelcacheMsg rc
Definition: sinval.h:118
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
static int relcache_callback_count
Definition: inval.c:209
RelcacheCallbackFunction function
Definition: inval.c:205
void RelationMapInvalidate(bool shared)
Definition: relmapper.c:387
#define FATAL
Definition: elog.h:52
#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:350
SharedInvalCatalogMsg cat
Definition: sinval.h:117
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:510
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1450
Oid MyDatabaseId
Definition: globals.c:77
#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:1351
void CatalogCacheFlushCatalog(Oid catId)
Definition: catcache.c:610
BackendId backend
Definition: relfilenode.h:75
void RelationCacheInvalidateEntry(Oid relationId)
Definition: relcache.c:2720
uint16 backend_lo
Definition: sinval.h:92
#define SHAREDINVALCATALOG_ID
Definition: sinval.h:67
void RelationCacheInvalidate(void)
Definition: relcache.c:2764
int i
RelFileNode rnode
Definition: sinval.h:93
#define SHAREDINVALSMGR_ID
Definition: sinval.h:85
#define elog
Definition: elog.h:219
static void MakeSharedInvalidMessagesArray ( const SharedInvalidationMessage msgs,
int  n 
)
static

Definition at line 766 of file inval.c.

References FIRSTCHUNKSIZE, maxSharedInvalidMessagesArray, NULL, numSharedInvalidMessagesArray, palloc(), and repalloc().

Referenced by xactGetCommittedInvalidationMessages().

767 {
768  /*
769  * Initialise array first time through in each commit
770  */
772  {
775 
776  /*
777  * Although this is being palloc'd we don't actually free it directly.
778  * We're so close to EOXact that we now we're going to lose it anyhow.
779  */
781  * sizeof(SharedInvalidationMessage));
782  }
783 
785  {
788 
791  * sizeof(SharedInvalidationMessage));
792  }
793 
794  /*
795  * Append the next chunk onto the array
796  */
798  msgs, n * sizeof(SharedInvalidationMessage));
800 }
#define FIRSTCHUNKSIZE
static SharedInvalidationMessage * SharedInvalidMessagesArray
Definition: inval.c:173
static int numSharedInvalidMessagesArray
Definition: inval.c:174
#define NULL
Definition: c.h:229
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:963
static int maxSharedInvalidMessagesArray
Definition: inval.c:175
void * palloc(Size size)
Definition: mcxt.c:849
void PostPrepare_Inval ( void  )

Definition at line 757 of file inval.c.

References AtEOXact_Inval().

Referenced by PrepareTransaction().

758 {
759  AtEOXact_Inval(false);
760 }
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:929
static void PrepareInvalidationState ( void  )
static

Definition at line 720 of file inval.c.

References Assert, GetCurrentTransactionNestLevel(), MemoryContextAllocZero(), TransInvalidationInfo::my_level, NULL, TransInvalidationInfo::parent, TopTransactionContext, and transInvalInfo.

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

721 {
722  TransInvalidationInfo *myInfo;
723 
724  if (transInvalInfo != NULL &&
726  return;
727 
728  myInfo = (TransInvalidationInfo *)
730  sizeof(TransInvalidationInfo));
731  myInfo->parent = transInvalInfo;
733 
734  /*
735  * If there's any previous entry, this one should be for a deeper nesting
736  * level.
737  */
739  myInfo->my_level > transInvalInfo->my_level);
740 
741  transInvalInfo = myInfo;
742 }
MemoryContext TopTransactionContext
Definition: mcxt.c:48
struct TransInvalidationInfo * parent
Definition: inval.c:156
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:742
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:761
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676
void ProcessCommittedInvalidationMessages ( SharedInvalidationMessage msgs,
int  nmsgs,
bool  RelcacheInitFileInval,
Oid  dbid,
Oid  tsid 
)

Definition at line 872 of file inval.c.

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

Referenced by standby_redo(), and xact_redo_commit().

875 {
876  if (nmsgs <= 0)
877  return;
878 
879  elog(trace_recovery(DEBUG4), "replaying commit with %d messages%s", nmsgs,
880  (RelcacheInitFileInval ? " and relcache file invalidation" : ""));
881 
882  if (RelcacheInitFileInval)
883  {
884  /*
885  * RelationCacheInitFilePreInvalidate requires DatabasePath to be set,
886  * but we should not use SetDatabasePath during recovery, since it is
887  * intended to be used only once by normal backends. Hence, a quick
888  * hack: set DatabasePath directly then unset after use.
889  */
890  DatabasePath = GetDatabasePath(dbid, tsid);
891  elog(trace_recovery(DEBUG4), "removing relcache init file in \"%s\"",
892  DatabasePath);
895  DatabasePath = NULL;
896  }
897 
898  SendSharedInvalidMessages(msgs, nmsgs);
899 
900  if (RelcacheInitFileInval)
902 }
#define DEBUG4
Definition: elog.h:22
int trace_recovery(int trace_level)
Definition: elog.c:3753
void pfree(void *pointer)
Definition: mcxt.c:950
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:108
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6084
char * DatabasePath
Definition: globals.c:85
#define NULL
Definition: c.h:229
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6058
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:49
#define elog
Definition: elog.h:219
static void ProcessInvalidationMessages ( InvalidationListHeader hdr,
void(*)(SharedInvalidationMessage *msg)  func 
)
static

Definition at line 454 of file inval.c.

References InvalidationListHeader::cclist, ProcessMessageList, and InvalidationListHeader::rclist.

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

456 {
457  ProcessMessageList(hdr->cclist, func(msg));
458  ProcessMessageList(hdr->rclist, func(msg));
459 }
#define ProcessMessageList(listHdr, codeFragment)
Definition: inval.c:293
InvalidationChunk * cclist
Definition: inval.c:132
InvalidationChunk * rclist
Definition: inval.c:133
static void ProcessInvalidationMessagesMulti ( InvalidationListHeader hdr,
void(*)(const SharedInvalidationMessage *msgs, int n)  func 
)
static

Definition at line 466 of file inval.c.

References InvalidationListHeader::cclist, ProcessMessageListMulti, and InvalidationListHeader::rclist.

Referenced by AtEOXact_Inval(), and xactGetCommittedInvalidationMessages().

468 {
469  ProcessMessageListMulti(hdr->cclist, func(msgs, n));
470  ProcessMessageListMulti(hdr->rclist, func(msgs, n));
471 }
#define ProcessMessageListMulti(listHdr, codeFragment)
Definition: inval.c:313
InvalidationChunk * cclist
Definition: inval.c:132
InvalidationChunk * rclist
Definition: inval.c:133
static void RegisterCatalogInvalidation ( Oid  dbId,
Oid  catId 
)
static

Definition at line 498 of file inval.c.

References AddCatalogInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateCatalog().

499 {
501  dbId, catId);
502 }
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
InvalidationListHeader CurrentCmdInvalidMsgs
Definition: inval.c:162
static void AddCatalogInvalidationMessage(InvalidationListHeader *hdr, Oid dbId, Oid catId)
Definition: inval.c:365
static void RegisterCatcacheInvalidation ( int  cacheId,
uint32  hashValue,
Oid  dbId 
)
static

Definition at line 484 of file inval.c.

References AddCatcacheInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateHeapTuple().

487 {
489  cacheId, hashValue, dbId);
490 }
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
InvalidationListHeader CurrentCmdInvalidMsgs
Definition: inval.c:162
static void AddCatcacheInvalidationMessage(InvalidationListHeader *hdr, int id, uint32 hashValue, Oid dbId)
Definition: inval.c:337
static void RegisterRelcacheInvalidation ( Oid  dbId,
Oid  relId 
)
static

Definition at line 510 of file inval.c.

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

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

511 {
513  dbId, relId);
514 
515  /*
516  * Most of the time, relcache invalidation is associated with system
517  * catalog updates, but there are a few cases where it isn't. Quick hack
518  * to ensure that the next CommandCounterIncrement() will think that we
519  * need to do CommandEndInvalidationMessages().
520  */
521  (void) GetCurrentCommandId(true);
522 
523  /*
524  * If the relation being invalidated is one of those cached in the local
525  * relcache init file, mark that we need to zap that file at commit. Same
526  * is true when we are invalidating whole relcache.
527  */
528  if (OidIsValid(dbId) &&
529  (RelationIdIsInInitFile(relId) || relId == InvalidOid))
531 }
bool RelationIdIsInInitFile(Oid relationId)
Definition: relcache.c:5975
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
#define OidIsValid(objectId)
Definition: c.h:538
InvalidationListHeader CurrentCmdInvalidMsgs
Definition: inval.c:162
bool RelcacheInitFileInval
Definition: inval.c:168
#define InvalidOid
Definition: postgres_ext.h:36
static void AddRelcacheInvalidationMessage(InvalidationListHeader *hdr, Oid dbId, Oid relId)
Definition: inval.c:383
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:687
static void RegisterSnapshotInvalidation ( Oid  dbId,
Oid  relId 
)
static

Definition at line 540 of file inval.c.

References AddSnapshotInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateHeapTuple().

541 {
543  dbId, relId);
544 }
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
InvalidationListHeader CurrentCmdInvalidMsgs
Definition: inval.c:162
static void AddSnapshotInvalidationMessage(InvalidationListHeader *hdr, Oid dbId, Oid relId)
Definition: inval.c:413
int xactGetCommittedInvalidationMessages ( SharedInvalidationMessage **  msgs,
bool RelcacheInitFileInval 
)

Definition at line 816 of file inval.c.

References Assert, TransInvalidationInfo::CurrentCmdInvalidMsgs, CurTransactionContext, MakeSharedInvalidMessagesArray(), MemoryContextSwitchTo(), TransInvalidationInfo::my_level, NULL, numSharedInvalidMessagesArray, TransInvalidationInfo::parent, TransInvalidationInfo::PriorCmdInvalidMsgs, ProcessInvalidationMessagesMulti(), TransInvalidationInfo::RelcacheInitFileInval, and SharedInvalidMessagesArray.

Referenced by RecordTransactionCommit(), and StartPrepare().

818 {
819  MemoryContext oldcontext;
820 
821  /* Quick exit if we haven't done anything with invalidation messages. */
822  if (transInvalInfo == NULL)
823  {
824  *RelcacheInitFileInval = false;
825  *msgs = NULL;
826  return 0;
827  }
828 
829  /* Must be at top of stack */
831 
832  /*
833  * Relcache init file invalidation requires processing both before and
834  * after we send the SI messages. However, we need not do anything unless
835  * we committed.
836  */
837  *RelcacheInitFileInval = transInvalInfo->RelcacheInitFileInval;
838 
839  /*
840  * Walk through TransInvalidationInfo to collect all the messages into a
841  * single contiguous array of invalidation messages. It must be contiguous
842  * so we can copy directly into WAL message. Maintain the order that they
843  * would be processed in by AtEOXact_Inval(), to ensure emulated behaviour
844  * in redo is as similar as possible to original. We want the same bugs,
845  * if any, not new ones.
846  */
848 
853  MemoryContextSwitchTo(oldcontext);
854 
857 
859 
861 }
static SharedInvalidationMessage * SharedInvalidMessagesArray
Definition: inval.c:173
InvalidationListHeader PriorCmdInvalidMsgs
Definition: inval.c:165
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext CurTransactionContext
Definition: mcxt.c:49
struct TransInvalidationInfo * parent
Definition: inval.c:156
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:171
InvalidationListHeader CurrentCmdInvalidMsgs
Definition: inval.c:162
static void MakeSharedInvalidMessagesArray(const SharedInvalidationMessage *msgs, int n)
Definition: inval.c:766
static int numSharedInvalidMessagesArray
Definition: inval.c:174
static void ProcessInvalidationMessagesMulti(InvalidationListHeader *hdr, void(*func)(const SharedInvalidationMessage *msgs, int n))
Definition: inval.c:466
bool RelcacheInitFileInval
Definition: inval.c:168
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676

Variable Documentation

int maxSharedInvalidMessagesArray
static

Definition at line 175 of file inval.c.

Referenced by MakeSharedInvalidMessagesArray().

int numSharedInvalidMessagesArray
static
int relcache_callback_count = 0
static
SharedInvalidationMessage* SharedInvalidMessagesArray
static

Definition at line 173 of file inval.c.

Referenced by xactGetCommittedInvalidationMessages().

int syscache_callback_count = 0
static

Definition at line 201 of file inval.c.

Referenced by CacheRegisterSyscacheCallback(), and InvalidateSystemCaches().

int16 syscache_callback_links[SysCacheSize]
static

Definition at line 199 of file inval.c.

Referenced by CacheRegisterSyscacheCallback(), and CallSyscacheCallbacks().

TransInvalidationInfo* transInvalInfo = NULL
static

Definition at line 171 of file inval.c.

Referenced by AtEOSubXact_Inval(), and PrepareInvalidationState().