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   32
 
#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 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 184 of file inval.c.

Referenced by CacheRegisterRelcacheCallback().

#define MAX_SYSCACHE_CALLBACKS   32

Definition at line 183 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 285 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 305 of file inval.c.

Referenced by ProcessInvalidationMessagesMulti().

Typedef Documentation

Function Documentation

void AcceptInvalidationMessages ( void  )

Definition at line 672 of file inval.c.

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

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

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

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

359 {
361 
363  msg.cat.dbId = dbId;
364  msg.cat.catId = catId;
365  /* check AddCatcacheInvalidationMessage() for an explanation */
366  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
367 
368  AddInvalidationMessage(&hdr->cclist, &msg);
369 }
static void AddInvalidationMessage(InvalidationChunk **listHdr, SharedInvalidationMessage *msg)
Definition: inval.c:219
#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 329 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().

331 {
333 
334  Assert(id < CHAR_MAX);
335  msg.cc.id = (int8) id;
336  msg.cc.dbId = dbId;
337  msg.cc.hashValue = hashValue;
338 
339  /*
340  * Define padding bytes in SharedInvalidationMessage structs to be
341  * defined. Otherwise the sinvaladt.c ringbuffer, which is accessed by
342  * multiple processes, will cause spurious valgrind warnings about
343  * undefined memory being used. That's because valgrind remembers the
344  * undefined bytes from the last local process's store, not realizing that
345  * another process has written since, filling the previously uninitialized
346  * bytes
347  */
348  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
349 
350  AddInvalidationMessage(&hdr->cclist, &msg);
351 }
static void AddInvalidationMessage(InvalidationChunk **listHdr, SharedInvalidationMessage *msg)
Definition: inval.c:219
#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:675
static void AddInvalidationMessage ( InvalidationChunk **  listHdr,
SharedInvalidationMessage msg 
)
static

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

221 {
222  InvalidationChunk *chunk = *listHdr;
223 
224  if (chunk == NULL)
225  {
226  /* First time through; create initial chunk */
227 #define FIRSTCHUNKSIZE 32
228  chunk = (InvalidationChunk *)
230  offsetof(InvalidationChunk, msgs) +
232  chunk->nitems = 0;
233  chunk->maxitems = FIRSTCHUNKSIZE;
234  chunk->next = *listHdr;
235  *listHdr = chunk;
236  }
237  else if (chunk->nitems >= chunk->maxitems)
238  {
239  /* Need another chunk; double size of last chunk */
240  int chunksize = 2 * chunk->maxitems;
241 
242  chunk = (InvalidationChunk *)
244  offsetof(InvalidationChunk, msgs) +
245  chunksize * sizeof(SharedInvalidationMessage));
246  chunk->nitems = 0;
247  chunk->maxitems = chunksize;
248  chunk->next = *listHdr;
249  *listHdr = chunk;
250  }
251  /* Okay, add message to current chunk */
252  chunk->msgs[chunk->nitems] = *msg;
253  chunk->nitems++;
254 }
#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 375 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().

377 {
379 
380  /*
381  * Don't add a duplicate item.
382  * We assume dbId need not be checked because it will never change.
383  * InvalidOid for relId means all relations so we don't need to add
384  * individual ones when it is present.
385  */
387  if (msg->rc.id == SHAREDINVALRELCACHE_ID &&
388  (msg->rc.relId == relId ||
389  msg->rc.relId == InvalidOid))
390  return);
391 
392  /* OK, add the item */
394  msg.rc.dbId = dbId;
395  msg.rc.relId = relId;
396  /* check AddCatcacheInvalidationMessage() for an explanation */
397  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
398 
399  AddInvalidationMessage(&hdr->rclist, &msg);
400 }
static void AddInvalidationMessage(InvalidationChunk **listHdr, SharedInvalidationMessage *msg)
Definition: inval.c:219
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
SharedInvalRelcacheMsg rc
Definition: sinval.h:118
#define ProcessMessageList(listHdr, codeFragment)
Definition: inval.c:285
#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 406 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().

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

Definition at line 261 of file inval.c.

References InvalidationChunk::next, and NULL.

Referenced by AppendInvalidationMessages().

263 {
264  InvalidationChunk *chunk = *srcHdr;
265 
266  if (chunk == NULL)
267  return; /* nothing to do */
268 
269  while (chunk->next != NULL)
270  chunk = chunk->next;
271 
272  chunk->next = *destHdr;
273 
274  *destHdr = *srcHdr;
275 
276  *srcHdr = NULL;
277 }
struct InvalidationChunk * next
Definition: inval.c:124
#define NULL
Definition: c.h:229
static void AppendInvalidationMessages ( InvalidationListHeader dest,
InvalidationListHeader src 
)
static

Definition at line 433 of file inval.c.

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

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

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

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

982 {
983  int my_level;
985 
986  /* Quick exit if no messages. */
987  if (myInfo == NULL)
988  return;
989 
990  /* Also bail out quickly if messages are not for this level. */
991  my_level = GetCurrentTransactionNestLevel();
992  if (myInfo->my_level != my_level)
993  {
994  Assert(myInfo->my_level < my_level);
995  return;
996  }
997 
998  if (isCommit)
999  {
1000  /* If CurrentCmdInvalidMsgs still has anything, fix it */
1002 
1003  /*
1004  * We create invalidation stack entries lazily, so the parent might
1005  * not have one. Instead of creating one, moving all the data over,
1006  * and then freeing our own, we can just adjust the level of our own
1007  * entry.
1008  */
1009  if (myInfo->parent == NULL || myInfo->parent->my_level < my_level - 1)
1010  {
1011  myInfo->my_level--;
1012  return;
1013  }
1014 
1015  /* Pass up my inval messages to parent */
1017  &myInfo->PriorCmdInvalidMsgs);
1018 
1019  /* Pending relcache inval becomes parent's problem too */
1020  if (myInfo->RelcacheInitFileInval)
1021  myInfo->parent->RelcacheInitFileInval = true;
1022 
1023  /* Pop the transaction state stack */
1024  transInvalInfo = myInfo->parent;
1025 
1026  /* Need not free anything else explicitly */
1027  pfree(myInfo);
1028  }
1029  else
1030  {
1033 
1034  /* Pop the transaction state stack */
1035  transInvalInfo = myInfo->parent;
1036 
1037  /* Need not free anything else explicitly */
1038  pfree(myInfo);
1039  }
1040 }
static void AppendInvalidationMessages(InvalidationListHeader *dest, InvalidationListHeader *src)
Definition: inval.c:433
InvalidationListHeader PriorCmdInvalidMsgs
Definition: inval.c:165
void CommandEndInvalidationMessages(void)
Definition: inval.c:1058
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:447
int GetCurrentTransactionNestLevel(void)
Definition: xact.c:761
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:547
void AtEOXact_Inval ( bool  isCommit)

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

923 {
924  /* Quick exit if no messages */
925  if (transInvalInfo == NULL)
926  return;
927 
928  /* Must be at top of stack */
930 
931  if (isCommit)
932  {
933  /*
934  * Relcache init file invalidation requires processing both before and
935  * after we send the SI messages. However, we need not do anything
936  * unless we committed.
937  */
940 
943 
946 
949  }
950  else
951  {
954  }
955 
956  /* Need not free anything explicitly */
960 }
static void AppendInvalidationMessages(InvalidationListHeader *dest, InvalidationListHeader *src)
Definition: inval.c:433
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:459
bool RelcacheInitFileInval
Definition: inval.c:168
static void ProcessInvalidationMessages(InvalidationListHeader *hdr, void(*func)(SharedInvalidationMessage *msg))
Definition: inval.c:447
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6057
#define NULL
Definition: c.h:229
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6031
#define Assert(condition)
Definition: c.h:675
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:49
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:547
void CacheInvalidateCatalog ( Oid  catalogId)

Definition at line 1201 of file inval.c.

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

Referenced by finish_heap_swap().

1202 {
1203  Oid databaseId;
1204 
1206 
1207  if (IsSharedRelation(catalogId))
1208  databaseId = InvalidOid;
1209  else
1210  databaseId = MyDatabaseId;
1211 
1212  RegisterCatalogInvalidation(databaseId, catalogId);
1213 }
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:713
Oid MyDatabaseId
Definition: globals.c:76
static void RegisterCatalogInvalidation(Oid dbId, Oid catId)
Definition: inval.c:491
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:219
#define InvalidOid
Definition: postgres_ext.h:36
void CacheInvalidateHeapTuple ( Relation  relation,
HeapTuple  tuple,
HeapTuple  newtuple 
)

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

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

Definition at line 1225 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(), heap_drop_with_catalog(), index_drop(), publication_add_relation(), reindex_index(), RemovePolicyById(), RemoveRewriteRuleById(), RemoveRoleFromObjectPolicy(), RemoveStatisticsById(), RemoveTriggerById(), rename_policy(), RenameRewriteRule(), renametrig(), SetRelationNumChecks(), StorePartitionBound(), and StorePartitionKey().

1226 {
1227  Oid databaseId;
1228  Oid relationId;
1229 
1231 
1232  relationId = RelationGetRelid(relation);
1233  if (relation->rd_rel->relisshared)
1234  databaseId = InvalidOid;
1235  else
1236  databaseId = MyDatabaseId;
1237 
1238  RegisterRelcacheInvalidation(databaseId, relationId);
1239 }
Form_pg_class rd_rel
Definition: rel.h:114
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:713
Oid MyDatabaseId
Definition: globals.c:76
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:503
#define RelationGetRelid(relation)
Definition: rel.h:417
void CacheInvalidateRelcacheAll ( void  )

Definition at line 1249 of file inval.c.

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

Referenced by AlterPublicationOptions().

1250 {
1252 
1254 }
static void PrepareInvalidationState(void)
Definition: inval.c:713
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:503
void CacheInvalidateRelcacheByRelid ( Oid  relid)

Definition at line 1284 of file inval.c.

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

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

1285 {
1286  HeapTuple tup;
1287 
1289 
1290  tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
1291  if (!HeapTupleIsValid(tup))
1292  elog(ERROR, "cache lookup failed for relation %u", relid);
1294  ReleaseSysCache(tup);
1295 }
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
static void PrepareInvalidationState(void)
Definition: inval.c:713
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
Definition: inval.c:1261
#define elog
Definition: elog.h:219
void CacheInvalidateRelcacheByTuple ( HeapTuple  classTuple)

Definition at line 1261 of file inval.c.

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

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

1262 {
1263  Form_pg_class classtup = (Form_pg_class) GETSTRUCT(classTuple);
1264  Oid databaseId;
1265  Oid relationId;
1266 
1268 
1269  relationId = HeapTupleGetOid(classTuple);
1270  if (classtup->relisshared)
1271  databaseId = InvalidOid;
1272  else
1273  databaseId = MyDatabaseId;
1274  RegisterRelcacheInvalidation(databaseId, relationId);
1275 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
unsigned int Oid
Definition: postgres_ext.h:31
static void PrepareInvalidationState(void)
Definition: inval.c:713
Oid MyDatabaseId
Definition: globals.c:76
#define InvalidOid
Definition: postgres_ext.h:36
static void RegisterRelcacheInvalidation(Oid dbId, Oid relId)
Definition: inval.c:503
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 1354 of file inval.c.

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

Referenced by write_relmap_file().

1355 {
1357 
1358  msg.rm.id = SHAREDINVALRELMAP_ID;
1359  msg.rm.dbId = databaseId;
1360  /* check AddCatcacheInvalidationMessage() for an explanation */
1361  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1362 
1363  SendSharedInvalidMessages(&msg, 1);
1364 }
#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 1324 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().

1325 {
1327 
1328  msg.sm.id = SHAREDINVALSMGR_ID;
1329  msg.sm.backend_hi = rnode.backend >> 16;
1330  msg.sm.backend_lo = rnode.backend & 0xffff;
1331  msg.sm.rnode = rnode.node;
1332  /* check AddCatcacheInvalidationMessage() for an explanation */
1333  VALGRIND_MAKE_MEM_DEFINED(&msg, sizeof(msg));
1334 
1335  SendSharedInvalidMessages(&msg, 1);
1336 }
#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 1405 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().

1407 {
1409  elog(FATAL, "out of relcache_callback_list slots");
1410 
1413 
1415 }
#define MAX_RELCACHE_CALLBACKS
Definition: inval.c:184
static int relcache_callback_count
Definition: inval.c:201
RelcacheCallbackFunction function
Definition: inval.c:197
#define FATAL
Definition: elog.h:52
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
void * arg
#define elog
Definition: elog.h:219
void CacheRegisterSyscacheCallback ( int  cacheid,
SyscacheCallbackFunction  func,
Datum  arg 
)

Definition at line 1381 of file inval.c.

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

Referenced by ApplyWorkerMain(), BuildEventTriggerCache(), find_oper_cache_entry(), 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().

1384 {
1386  elog(FATAL, "out of syscache_callback_list slots");
1387 
1391 
1393 }
#define FATAL
Definition: elog.h:52
#define MAX_SYSCACHE_CALLBACKS
Definition: inval.c:183
static int syscache_callback_count
Definition: inval.c:193
void * arg
#define elog
Definition: elog.h:219
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
SyscacheCallbackFunction function
Definition: inval.c:189
void CallSyscacheCallbacks ( int  cacheid,
uint32  hashvalue 
)

Definition at line 1424 of file inval.c.

References SYSCACHECALLBACK::arg, SYSCACHECALLBACK::function, i, SYSCACHECALLBACK::id, syscache_callback_count, and syscache_callback_list.

Referenced by CatalogCacheFlushCatalog(), and LocalExecuteInvalidationMessage().

1425 {
1426  int i;
1427 
1428  for (i = 0; i < syscache_callback_count; i++)
1429  {
1430  struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
1431 
1432  if (ccitem->id == cacheid)
1433  (*ccitem->function) (ccitem->arg, cacheid, hashvalue);
1434  }
1435 }
static int syscache_callback_count
Definition: inval.c:193
int i
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
SyscacheCallbackFunction function
Definition: inval.c:189
void CommandEndInvalidationMessages ( void  )

Definition at line 1058 of file inval.c.

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

Referenced by AtCCI_LocalCache(), and AtEOSubXact_Inval().

1059 {
1060  /*
1061  * You might think this shouldn't be called outside any transaction, but
1062  * bootstrap does it, and also ABORT issued when not in a transaction. So
1063  * just quietly return if no state to work on.
1064  */
1065  if (transInvalInfo == NULL)
1066  return;
1067 
1072 }
static void AppendInvalidationMessages(InvalidationListHeader *dest, InvalidationListHeader *src)
Definition: inval.c:433
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:447
#define NULL
Definition: c.h:229
void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
Definition: inval.c:547
void InvalidateSystemCaches ( void  )

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

635 {
636  int i;
637 
640  RelationCacheInvalidate(); /* gets smgr and relmap too */
641 
642  for (i = 0; i < syscache_callback_count; i++)
643  {
644  struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
645 
646  (*ccitem->function) (ccitem->arg, ccitem->id, 0);
647  }
648 
649  for (i = 0; i < relcache_callback_count; i++)
650  {
651  struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
652 
653  (*ccitem->function) (ccitem->arg, InvalidOid);
654  }
655 }
static int relcache_callback_count
Definition: inval.c:201
RelcacheCallbackFunction function
Definition: inval.c:197
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:506
static int syscache_callback_count
Definition: inval.c:193
#define InvalidOid
Definition: postgres_ext.h:36
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
void ResetCatalogCaches(void)
Definition: catcache.c:645
void RelationCacheInvalidate(void)
Definition: relcache.c:2756
int i
static struct SYSCACHECALLBACK syscache_callback_list[MAX_SYSCACHE_CALLBACKS]
SyscacheCallbackFunction function
Definition: inval.c:189
void LocalExecuteInvalidationMessage ( SharedInvalidationMessage msg)

Definition at line 547 of file inval.c.

References RELCACHECALLBACK::arg, RelFileNodeBackend::backend, SharedInvalSmgrMsg::backend_hi, SharedInvalSmgrMsg::backend_lo, CallSyscacheCallbacks(), SharedInvalidationMessage::cat, CatalogCacheFlushCatalog(), CatalogCacheIdInvalidate(), 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, and smgrclosenode().

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

548 {
549  if (msg->id >= 0)
550  {
551  if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid)
552  {
554 
556 
557  CallSyscacheCallbacks(msg->cc.id, msg->cc.hashValue);
558  }
559  }
560  else if (msg->id == SHAREDINVALCATALOG_ID)
561  {
562  if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid)
563  {
565 
567 
568  /* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */
569  }
570  }
571  else if (msg->id == SHAREDINVALRELCACHE_ID)
572  {
573  if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid)
574  {
575  int i;
576 
577  if (msg->rc.relId == InvalidOid)
579  else
581 
582  for (i = 0; i < relcache_callback_count; i++)
583  {
584  struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
585 
586  (*ccitem->function) (ccitem->arg, msg->rc.relId);
587  }
588  }
589  }
590  else if (msg->id == SHAREDINVALSMGR_ID)
591  {
592  /*
593  * We could have smgr entries for relations of other databases, so no
594  * short-circuit test is possible here.
595  */
596  RelFileNodeBackend rnode;
597 
598  rnode.node = msg->sm.rnode;
599  rnode.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo;
600  smgrclosenode(rnode);
601  }
602  else if (msg->id == SHAREDINVALRELMAP_ID)
603  {
604  /* We only care about our own database and shared catalogs */
605  if (msg->rm.dbId == InvalidOid)
606  RelationMapInvalidate(true);
607  else if (msg->rm.dbId == MyDatabaseId)
608  RelationMapInvalidate(false);
609  }
610  else if (msg->id == SHAREDINVALSNAPSHOT_ID)
611  {
612  /* We only care about our own database and shared catalogs */
613  if (msg->rm.dbId == InvalidOid)
615  else if (msg->rm.dbId == MyDatabaseId)
617  }
618  else
619  elog(FATAL, "unrecognized SI message ID: %d", msg->id);
620 }
SharedInvalRelcacheMsg rc
Definition: sinval.h:118
void CatalogCacheIdInvalidate(int cacheId, uint32 hashValue)
Definition: catcache.c:443
static int relcache_callback_count
Definition: inval.c:201
RelcacheCallbackFunction function
Definition: inval.c:197
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:506
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1424
Oid MyDatabaseId
Definition: globals.c:76
#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 CatalogCacheFlushCatalog(Oid catId)
Definition: catcache.c:675
BackendId backend
Definition: relfilenode.h:75
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
void RelationCacheInvalidateEntry(Oid relationId)
Definition: relcache.c:2712
uint16 backend_lo
Definition: sinval.h:92
#define SHAREDINVALCATALOG_ID
Definition: sinval.h:67
void RelationCacheInvalidate(void)
Definition: relcache.c:2756
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 759 of file inval.c.

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

Referenced by xactGetCommittedInvalidationMessages().

760 {
761  /*
762  * Initialise array first time through in each commit
763  */
765  {
768 
769  /*
770  * Although this is being palloc'd we don't actually free it directly.
771  * We're so close to EOXact that we now we're going to lose it anyhow.
772  */
774  * sizeof(SharedInvalidationMessage));
775  }
776 
778  {
781 
784  * sizeof(SharedInvalidationMessage));
785  }
786 
787  /*
788  * Append the next chunk onto the array
789  */
791  msgs, n * sizeof(SharedInvalidationMessage));
793 }
#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 750 of file inval.c.

References AtEOXact_Inval().

Referenced by PrepareTransaction().

751 {
752  AtEOXact_Inval(false);
753 }
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:922
static void PrepareInvalidationState ( void  )
static

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

714 {
715  TransInvalidationInfo *myInfo;
716 
717  if (transInvalInfo != NULL &&
719  return;
720 
721  myInfo = (TransInvalidationInfo *)
723  sizeof(TransInvalidationInfo));
724  myInfo->parent = transInvalInfo;
726 
727  /*
728  * If there's any previous entry, this one should be for a deeper nesting
729  * level.
730  */
732  myInfo->my_level > transInvalInfo->my_level);
733 
734  transInvalInfo = myInfo;
735 }
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:675
void ProcessCommittedInvalidationMessages ( SharedInvalidationMessage msgs,
int  nmsgs,
bool  RelcacheInitFileInval,
Oid  dbid,
Oid  tsid 
)

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

868 {
869  if (nmsgs <= 0)
870  return;
871 
872  elog(trace_recovery(DEBUG4), "replaying commit with %d messages%s", nmsgs,
873  (RelcacheInitFileInval ? " and relcache file invalidation" : ""));
874 
875  if (RelcacheInitFileInval)
876  {
877  /*
878  * RelationCacheInitFilePreInvalidate requires DatabasePath to be set,
879  * but we should not use SetDatabasePath during recovery, since it is
880  * intended to be used only once by normal backends. Hence, a quick
881  * hack: set DatabasePath directly then unset after use.
882  */
883  DatabasePath = GetDatabasePath(dbid, tsid);
884  elog(trace_recovery(DEBUG4), "removing relcache init file in \"%s\"",
885  DatabasePath);
888  DatabasePath = NULL;
889  }
890 
891  SendSharedInvalidMessages(msgs, nmsgs);
892 
893  if (RelcacheInitFileInval)
895 }
#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:6057
char * DatabasePath
Definition: globals.c:84
#define NULL
Definition: c.h:229
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6031
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 447 of file inval.c.

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

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

449 {
450  ProcessMessageList(hdr->cclist, func(msg));
451  ProcessMessageList(hdr->rclist, func(msg));
452 }
#define ProcessMessageList(listHdr, codeFragment)
Definition: inval.c:285
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 459 of file inval.c.

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

Referenced by AtEOXact_Inval(), and xactGetCommittedInvalidationMessages().

461 {
462  ProcessMessageListMulti(hdr->cclist, func(msgs, n));
463  ProcessMessageListMulti(hdr->rclist, func(msgs, n));
464 }
#define ProcessMessageListMulti(listHdr, codeFragment)
Definition: inval.c:305
InvalidationChunk * cclist
Definition: inval.c:132
InvalidationChunk * rclist
Definition: inval.c:133
static void RegisterCatalogInvalidation ( Oid  dbId,
Oid  catId 
)
static

Definition at line 491 of file inval.c.

References AddCatalogInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateCatalog().

492 {
494  dbId, catId);
495 }
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:357
static void RegisterCatcacheInvalidation ( int  cacheId,
uint32  hashValue,
Oid  dbId 
)
static

Definition at line 477 of file inval.c.

References AddCatcacheInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateHeapTuple().

480 {
482  cacheId, hashValue, dbId);
483 }
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:329
static void RegisterRelcacheInvalidation ( Oid  dbId,
Oid  relId 
)
static

Definition at line 503 of file inval.c.

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

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

504 {
506  dbId, relId);
507 
508  /*
509  * Most of the time, relcache invalidation is associated with system
510  * catalog updates, but there are a few cases where it isn't. Quick hack
511  * to ensure that the next CommandCounterIncrement() will think that we
512  * need to do CommandEndInvalidationMessages().
513  */
514  (void) GetCurrentCommandId(true);
515 
516  /*
517  * If the relation being invalidated is one of those cached in the local
518  * relcache init file, mark that we need to zap that file at commit.
519  * Same is true when we are invalidating whole relcache.
520  */
521  if (OidIsValid(dbId) &&
522  (RelationIdIsInInitFile(relId) || relId == InvalidOid))
524 }
bool RelationIdIsInInitFile(Oid relationId)
Definition: relcache.c:5948
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:375
CommandId GetCurrentCommandId(bool used)
Definition: xact.c:687
static void RegisterSnapshotInvalidation ( Oid  dbId,
Oid  relId 
)
static

Definition at line 533 of file inval.c.

References AddSnapshotInvalidationMessage(), and TransInvalidationInfo::CurrentCmdInvalidMsgs.

Referenced by CacheInvalidateHeapTuple().

534 {
536  dbId, relId);
537 }
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:406
int xactGetCommittedInvalidationMessages ( SharedInvalidationMessage **  msgs,
bool RelcacheInitFileInval 
)

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

811 {
812  MemoryContext oldcontext;
813 
814  /* Quick exit if we haven't done anything with invalidation messages. */
815  if (transInvalInfo == NULL)
816  {
817  *RelcacheInitFileInval = false;
818  *msgs = NULL;
819  return 0;
820  }
821 
822  /* Must be at top of stack */
824 
825  /*
826  * Relcache init file invalidation requires processing both before and
827  * after we send the SI messages. However, we need not do anything unless
828  * we committed.
829  */
830  *RelcacheInitFileInval = transInvalInfo->RelcacheInitFileInval;
831 
832  /*
833  * Walk through TransInvalidationInfo to collect all the messages into a
834  * single contiguous array of invalidation messages. It must be contiguous
835  * so we can copy directly into WAL message. Maintain the order that they
836  * would be processed in by AtEOXact_Inval(), to ensure emulated behaviour
837  * in redo is as similar as possible to original. We want the same bugs,
838  * if any, not new ones.
839  */
841 
846  MemoryContextSwitchTo(oldcontext);
847 
850 
852 
854 }
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:759
static int numSharedInvalidMessagesArray
Definition: inval.c:174
static void ProcessInvalidationMessagesMulti(InvalidationListHeader *hdr, void(*func)(const SharedInvalidationMessage *msgs, int n))
Definition: inval.c:459
bool RelcacheInitFileInval
Definition: inval.c:168
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675

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
TransInvalidationInfo* transInvalInfo = NULL
static

Definition at line 171 of file inval.c.

Referenced by AtEOSubXact_Inval(), and PrepareInvalidationState().