PostgreSQL Source Code  git master
sinval.h File Reference
#include <signal.h>
#include "storage/relfilelocator.h"
Include dependency graph for sinval.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SharedInvalCatcacheMsg
 
struct  SharedInvalCatalogMsg
 
struct  SharedInvalRelcacheMsg
 
struct  SharedInvalSmgrMsg
 
struct  SharedInvalRelmapMsg
 
struct  SharedInvalSnapshotMsg
 
union  SharedInvalidationMessage
 

Macros

#define SHAREDINVALCATALOG_ID   (-1)
 
#define SHAREDINVALRELCACHE_ID   (-2)
 
#define SHAREDINVALSMGR_ID   (-3)
 
#define SHAREDINVALRELMAP_ID   (-4)
 
#define SHAREDINVALSNAPSHOT_ID   (-5)
 

Functions

void SendSharedInvalidMessages (const SharedInvalidationMessage *msgs, int n)
 
void ReceiveSharedInvalidMessages (void(*invalFunction)(SharedInvalidationMessage *msg), void(*resetFunction)(void))
 
void HandleCatchupInterrupt (void)
 
void ProcessCatchupInterrupt (void)
 
int xactGetCommittedInvalidationMessages (SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
 
int inplaceGetInvalidationMessages (SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
 
void ProcessCommittedInvalidationMessages (SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
 
void LocalExecuteInvalidationMessage (SharedInvalidationMessage *msg)
 

Variables

PGDLLIMPORT uint64 SharedInvalidMessageCounter
 
PGDLLIMPORT volatile sig_atomic_t catchupInterruptPending
 

Macro Definition Documentation

◆ SHAREDINVALCATALOG_ID

#define SHAREDINVALCATALOG_ID   (-1)

Definition at line 67 of file sinval.h.

◆ SHAREDINVALRELCACHE_ID

#define SHAREDINVALRELCACHE_ID   (-2)

Definition at line 76 of file sinval.h.

◆ SHAREDINVALRELMAP_ID

#define SHAREDINVALRELMAP_ID   (-4)

Definition at line 96 of file sinval.h.

◆ SHAREDINVALSMGR_ID

#define SHAREDINVALSMGR_ID   (-3)

Definition at line 85 of file sinval.h.

◆ SHAREDINVALSNAPSHOT_ID

#define SHAREDINVALSNAPSHOT_ID   (-5)

Definition at line 104 of file sinval.h.

Function Documentation

◆ HandleCatchupInterrupt()

void HandleCatchupInterrupt ( void  )

Definition at line 154 of file sinval.c.

155 {
156  /*
157  * Note: this is called by a SIGNAL HANDLER. You must be very wary what
158  * you do here.
159  */
160 
162 
163  /* make sure the event is processed in due course */
164  SetLatch(MyLatch);
165 }
struct Latch * MyLatch
Definition: globals.c:62
void SetLatch(Latch *latch)
Definition: latch.c:632
volatile sig_atomic_t catchupInterruptPending
Definition: sinval.c:39

References catchupInterruptPending, MyLatch, and SetLatch().

Referenced by procsignal_sigusr1_handler().

◆ inplaceGetInvalidationMessages()

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

Definition at line 1015 of file inval.c.

1017 {
1018  SharedInvalidationMessage *msgarray;
1019  int nummsgs;
1020  int nmsgs;
1021 
1022  /* Quick exit if we haven't done anything with invalidation messages. */
1023  if (inplaceInvalInfo == NULL)
1024  {
1025  *RelcacheInitFileInval = false;
1026  *msgs = NULL;
1027  return 0;
1028  }
1029 
1030  *RelcacheInitFileInval = inplaceInvalInfo->RelcacheInitFileInval;
1032  *msgs = msgarray = (SharedInvalidationMessage *)
1033  palloc(nummsgs * sizeof(SharedInvalidationMessage));
1034 
1035  nmsgs = 0;
1037  CatCacheMsgs,
1038  (memcpy(msgarray + nmsgs,
1039  msgs,
1040  n * sizeof(SharedInvalidationMessage)),
1041  nmsgs += n));
1043  RelCacheMsgs,
1044  (memcpy(msgarray + nmsgs,
1045  msgs,
1046  n * sizeof(SharedInvalidationMessage)),
1047  nmsgs += n));
1048  Assert(nmsgs == nummsgs);
1049 
1050  return nmsgs;
1051 }
#define Assert(condition)
Definition: c.h:812
#define NumMessagesInGroup(group)
Definition: inval.c:205
#define CatCacheMsgs
Definition: inval.c:169
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
Definition: inval.c:390
static InvalidationInfo * inplaceInvalInfo
Definition: inval.c:255
#define RelCacheMsgs
Definition: inval.c:170
void * palloc(Size size)
Definition: mcxt.c:1317
bool RelcacheInitFileInval
Definition: inval.c:234
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:231

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

Referenced by heap_inplace_update_and_unlock().

◆ LocalExecuteInvalidationMessage()

void LocalExecuteInvalidationMessage ( SharedInvalidationMessage msg)

Definition at line 762 of file inval.c.

763 {
764  if (msg->id >= 0)
765  {
766  if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid)
767  {
769 
770  SysCacheInvalidate(msg->cc.id, msg->cc.hashValue);
771 
772  CallSyscacheCallbacks(msg->cc.id, msg->cc.hashValue);
773  }
774  }
775  else if (msg->id == SHAREDINVALCATALOG_ID)
776  {
777  if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid)
778  {
780 
782 
783  /* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */
784  }
785  }
786  else if (msg->id == SHAREDINVALRELCACHE_ID)
787  {
788  if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid)
789  {
790  int i;
791 
792  if (msg->rc.relId == InvalidOid)
794  else
796 
797  for (i = 0; i < relcache_callback_count; i++)
798  {
799  struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
800 
801  ccitem->function(ccitem->arg, msg->rc.relId);
802  }
803  }
804  }
805  else if (msg->id == SHAREDINVALSMGR_ID)
806  {
807  /*
808  * We could have smgr entries for relations of other databases, so no
809  * short-circuit test is possible here.
810  */
811  RelFileLocatorBackend rlocator;
812 
813  rlocator.locator = msg->sm.rlocator;
814  rlocator.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo;
815  smgrreleaserellocator(rlocator);
816  }
817  else if (msg->id == SHAREDINVALRELMAP_ID)
818  {
819  /* We only care about our own database and shared catalogs */
820  if (msg->rm.dbId == InvalidOid)
821  RelationMapInvalidate(true);
822  else if (msg->rm.dbId == MyDatabaseId)
823  RelationMapInvalidate(false);
824  }
825  else if (msg->id == SHAREDINVALSNAPSHOT_ID)
826  {
827  /* We only care about our own database and shared catalogs */
828  if (msg->sn.dbId == InvalidOid)
830  else if (msg->sn.dbId == MyDatabaseId)
832  }
833  else
834  elog(FATAL, "unrecognized SI message ID: %d", msg->id);
835 }
void CatalogCacheFlushCatalog(Oid catId)
Definition: catcache.c:784
#define FATAL
Definition: elog.h:41
#define elog(elevel,...)
Definition: elog.h:225
Oid MyDatabaseId
Definition: globals.c:93
static int relcache_callback_count
Definition: inval.c:291
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1765
int i
Definition: isn.c:72
#define InvalidOid
Definition: postgres_ext.h:36
void RelationCacheInvalidate(bool debug_discard)
Definition: relcache.c:2959
void RelationCacheInvalidateEntry(Oid relationId)
Definition: relcache.c:2903
void RelationMapInvalidate(bool shared)
Definition: relmapper.c:468
#define SHAREDINVALCATALOG_ID
Definition: sinval.h:67
#define SHAREDINVALSMGR_ID
Definition: sinval.h:85
#define SHAREDINVALSNAPSHOT_ID
Definition: sinval.h:104
#define SHAREDINVALRELCACHE_ID
Definition: sinval.h:76
#define SHAREDINVALRELMAP_ID
Definition: sinval.h:96
void smgrreleaserellocator(RelFileLocatorBackend rlocator)
Definition: smgr.c:382
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:388
RelcacheCallbackFunction function
Definition: inval.c:287
RelFileLocator locator
uint16 backend_lo
Definition: sinval.h:92
RelFileLocator rlocator
Definition: sinval.h:93
void SysCacheInvalidate(int cacheId, uint32 hashValue)
Definition: syscache.c:698
SharedInvalCatcacheMsg cc
Definition: sinval.h:116
SharedInvalRelcacheMsg rc
Definition: sinval.h:118
SharedInvalCatalogMsg cat
Definition: sinval.h:117
SharedInvalSmgrMsg sm
Definition: sinval.h:119
SharedInvalSnapshotMsg sn
Definition: sinval.h:121
SharedInvalRelmapMsg rm
Definition: sinval.h:120

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

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

◆ ProcessCatchupInterrupt()

void ProcessCatchupInterrupt ( void  )

Definition at line 174 of file sinval.c.

175 {
177  {
178  /*
179  * What we need to do here is cause ReceiveSharedInvalidMessages() to
180  * run, which will do the necessary work and also reset the
181  * catchupInterruptPending flag. If we are inside a transaction we
182  * can just call AcceptInvalidationMessages() to do this. If we
183  * aren't, we start and immediately end a transaction; the call to
184  * AcceptInvalidationMessages() happens down inside transaction start.
185  *
186  * It is awfully tempting to just call AcceptInvalidationMessages()
187  * without the rest of the xact start/stop overhead, and I think that
188  * would actually work in the normal case; but I am not sure that
189  * things would clean up nicely if we got an error partway through.
190  */
192  {
193  elog(DEBUG4, "ProcessCatchupEvent inside transaction");
195  }
196  else
197  {
198  elog(DEBUG4, "ProcessCatchupEvent outside transaction");
201  }
202  }
203 }
#define DEBUG4
Definition: elog.h:27
void AcceptInvalidationMessages(void)
Definition: inval.c:863
bool IsTransactionOrTransactionBlock(void)
Definition: xact.c:4981
void StartTransactionCommand(void)
Definition: xact.c:3051
void CommitTransactionCommand(void)
Definition: xact.c:3149

References AcceptInvalidationMessages(), catchupInterruptPending, CommitTransactionCommand(), DEBUG4, elog, IsTransactionOrTransactionBlock(), and StartTransactionCommand().

Referenced by HandleAutoVacLauncherInterrupts(), and ProcessClientReadInterrupt().

◆ ProcessCommittedInvalidationMessages()

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

Definition at line 1062 of file inval.c.

1065 {
1066  if (nmsgs <= 0)
1067  return;
1068 
1069  elog(DEBUG4, "replaying commit with %d messages%s", nmsgs,
1070  (RelcacheInitFileInval ? " and relcache file invalidation" : ""));
1071 
1072  if (RelcacheInitFileInval)
1073  {
1074  elog(DEBUG4, "removing relcache init files for database %u", dbid);
1075 
1076  /*
1077  * RelationCacheInitFilePreInvalidate, when the invalidation message
1078  * is for a specific database, requires DatabasePath to be set, but we
1079  * should not use SetDatabasePath during recovery, since it is
1080  * intended to be used only once by normal backends. Hence, a quick
1081  * hack: set DatabasePath directly then unset after use.
1082  */
1083  if (OidIsValid(dbid))
1084  DatabasePath = GetDatabasePath(dbid, tsid);
1085 
1087 
1088  if (OidIsValid(dbid))
1089  {
1091  DatabasePath = NULL;
1092  }
1093  }
1094 
1095  SendSharedInvalidMessages(msgs, nmsgs);
1096 
1097  if (RelcacheInitFileInval)
1099 }
#define OidIsValid(objectId)
Definition: c.h:729
char * DatabasePath
Definition: globals.c:103
void pfree(void *pointer)
Definition: mcxt.c:1521
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6813
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6788
char * GetDatabasePath(Oid dbOid, Oid spcOid)
Definition: relpath.c:110
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:47

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

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

◆ ReceiveSharedInvalidMessages()

void ReceiveSharedInvalidMessages ( void(*)(SharedInvalidationMessage *msg)  invalFunction,
void(*)(void)  resetFunction 
)

Definition at line 69 of file sinval.c.

71 {
72 #define MAXINVALMSGS 32
73  static SharedInvalidationMessage messages[MAXINVALMSGS];
74 
75  /*
76  * We use volatile here to prevent bugs if a compiler doesn't realize that
77  * recursion is a possibility ...
78  */
79  static volatile int nextmsg = 0;
80  static volatile int nummsgs = 0;
81 
82  /* Deal with any messages still pending from an outer recursion */
83  while (nextmsg < nummsgs)
84  {
85  SharedInvalidationMessage msg = messages[nextmsg++];
86 
88  invalFunction(&msg);
89  }
90 
91  do
92  {
93  int getResult;
94 
95  nextmsg = nummsgs = 0;
96 
97  /* Try to get some more messages */
98  getResult = SIGetDataEntries(messages, MAXINVALMSGS);
99 
100  if (getResult < 0)
101  {
102  /* got a reset message */
103  elog(DEBUG4, "cache state reset");
105  resetFunction();
106  break; /* nothing more to do */
107  }
108 
109  /* Process them, being wary that a recursive call might eat some */
110  nextmsg = 0;
111  nummsgs = getResult;
112 
113  while (nextmsg < nummsgs)
114  {
115  SharedInvalidationMessage msg = messages[nextmsg++];
116 
118  invalFunction(&msg);
119  }
120 
121  /*
122  * We only need to loop if the last SIGetDataEntries call (which might
123  * have been within a recursive call) returned a full buffer.
124  */
125  } while (nummsgs == MAXINVALMSGS);
126 
127  /*
128  * We are now caught up. If we received a catchup signal, reset that
129  * flag, and call SICleanupQueue(). This is not so much because we need
130  * to flush dead messages right now, as that we want to pass on the
131  * catchup signal to the next slowest backend. "Daisy chaining" the
132  * catchup signal this way avoids creating spikes in system load for what
133  * should be just a background maintenance activity.
134  */
136  {
137  catchupInterruptPending = false;
138  elog(DEBUG4, "sinval catchup complete, cleaning queue");
139  SICleanupQueue(false, 0);
140  }
141 }
uint64 SharedInvalidMessageCounter
Definition: sinval.c:24
#define MAXINVALMSGS
void SICleanupQueue(bool callerHasWriteLock, int minFree)
Definition: sinvaladt.c:576
int SIGetDataEntries(SharedInvalidationMessage *data, int datasize)
Definition: sinvaladt.c:472

References catchupInterruptPending, DEBUG4, elog, MAXINVALMSGS, SharedInvalidMessageCounter, SICleanupQueue(), and SIGetDataEntries().

Referenced by AcceptInvalidationMessages().

◆ SendSharedInvalidMessages()

void SendSharedInvalidMessages ( const SharedInvalidationMessage msgs,
int  n 
)

Definition at line 47 of file sinval.c.

48 {
49  SIInsertDataEntries(msgs, n);
50 }
void SIInsertDataEntries(const SharedInvalidationMessage *data, int n)
Definition: sinvaladt.c:369

References SIInsertDataEntries().

Referenced by AtEOXact_Inval(), AtInplace_Inval(), CacheInvalidateRelmap(), CacheInvalidateSmgr(), FinishPreparedTransaction(), and ProcessCommittedInvalidationMessages().

◆ xactGetCommittedInvalidationMessages()

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

Definition at line 939 of file inval.c.

941 {
942  SharedInvalidationMessage *msgarray;
943  int nummsgs;
944  int nmsgs;
945 
946  /* Quick exit if we haven't done anything with invalidation messages. */
947  if (transInvalInfo == NULL)
948  {
949  *RelcacheInitFileInval = false;
950  *msgs = NULL;
951  return 0;
952  }
953 
954  /* Must be at top of stack */
956 
957  /*
958  * Relcache init file invalidation requires processing both before and
959  * after we send the SI messages. However, we need not do anything unless
960  * we committed.
961  */
962  *RelcacheInitFileInval = transInvalInfo->ii.RelcacheInitFileInval;
963 
964  /*
965  * Collect all the pending messages into a single contiguous array of
966  * invalidation messages, to simplify what needs to happen while building
967  * the commit WAL message. Maintain the order that they would be
968  * processed in by AtEOXact_Inval(), to ensure emulated behaviour in redo
969  * is as similar as possible to original. We want the same bugs, if any,
970  * not new ones.
971  */
974 
975  *msgs = msgarray = (SharedInvalidationMessage *)
977  nummsgs * sizeof(SharedInvalidationMessage));
978 
979  nmsgs = 0;
981  CatCacheMsgs,
982  (memcpy(msgarray + nmsgs,
983  msgs,
984  n * sizeof(SharedInvalidationMessage)),
985  nmsgs += n));
987  CatCacheMsgs,
988  (memcpy(msgarray + nmsgs,
989  msgs,
990  n * sizeof(SharedInvalidationMessage)),
991  nmsgs += n));
993  RelCacheMsgs,
994  (memcpy(msgarray + nmsgs,
995  msgs,
996  n * sizeof(SharedInvalidationMessage)),
997  nmsgs += n));
999  RelCacheMsgs,
1000  (memcpy(msgarray + nmsgs,
1001  msgs,
1002  n * sizeof(SharedInvalidationMessage)),
1003  nmsgs += n));
1004  Assert(nmsgs == nummsgs);
1005 
1006  return nmsgs;
1007 }
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:253
MemoryContext CurTransactionContext
Definition: mcxt.c:155
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
struct TransInvalidationInfo * parent
Definition: inval.c:247
struct InvalidationInfo ii
Definition: inval.c:241
InvalidationMsgsGroup PriorCmdInvalidMsgs
Definition: inval.c:244

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

Referenced by RecordTransactionCommit(), and StartPrepare().

Variable Documentation

◆ catchupInterruptPending

PGDLLIMPORT volatile sig_atomic_t catchupInterruptPending
extern

◆ SharedInvalidMessageCounter

PGDLLIMPORT uint64 SharedInvalidMessageCounter
extern