PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
sinval.h File Reference
#include <signal.h>
#include "storage/relfilenode.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)
 
void ProcessCommittedInvalidationMessages (SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
 
void LocalExecuteInvalidationMessage (SharedInvalidationMessage *msg)
 

Variables

uint64 SharedInvalidMessageCounter
 
volatile sig_atomic_t catchupInterruptPending
 

Macro Definition Documentation

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

Function Documentation

void HandleCatchupInterrupt ( void  )

Definition at line 157 of file sinval.c.

References catchupInterruptPending, MyLatch, and SetLatch().

Referenced by procsignal_sigusr1_handler().

158 {
159  /*
160  * Note: this is called by a SIGNAL HANDLER. You must be very wary what
161  * you do here.
162  */
163 
165 
166  /* make sure the event is processed in due course */
167  SetLatch(MyLatch);
168 }
void SetLatch(volatile Latch *latch)
Definition: latch.c:414
struct Latch * MyLatch
Definition: globals.c:52
volatile sig_atomic_t catchupInterruptPending
Definition: sinval.c:41
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:1397
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
void ProcessCatchupInterrupt ( void  )

Definition at line 177 of file sinval.c.

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

Referenced by AutoVacLauncherMain(), and ProcessClientReadInterrupt().

178 {
180  {
181  /*
182  * What we need to do here is cause ReceiveSharedInvalidMessages() to
183  * run, which will do the necessary work and also reset the
184  * catchupInterruptPending flag. If we are inside a transaction we
185  * can just call AcceptInvalidationMessages() to do this. If we
186  * aren't, we start and immediately end a transaction; the call to
187  * AcceptInvalidationMessages() happens down inside transaction start.
188  *
189  * It is awfully tempting to just call AcceptInvalidationMessages()
190  * without the rest of the xact start/stop overhead, and I think that
191  * would actually work in the normal case; but I am not sure that
192  * things would clean up nicely if we got an error partway through.
193  */
195  {
196  elog(DEBUG4, "ProcessCatchupEvent inside transaction");
198  }
199  else
200  {
201  elog(DEBUG4, "ProcessCatchupEvent outside transaction");
204  }
205  }
206 }
void AcceptInvalidationMessages(void)
Definition: inval.c:679
void CommitTransactionCommand(void)
Definition: xact.c:2752
bool IsTransactionOrTransactionBlock(void)
Definition: xact.c:4473
#define DEBUG4
Definition: elog.h:22
void StartTransactionCommand(void)
Definition: xact.c:2681
volatile sig_atomic_t catchupInterruptPending
Definition: sinval.c:41
#define elog
Definition: elog.h:219
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(), 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:949
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:108
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6084
char * DatabasePath
Definition: globals.c:85
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6058
void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n)
Definition: sinval.c:49
#define elog
Definition: elog.h:219
void ReceiveSharedInvalidMessages ( void(*)(SharedInvalidationMessage *msg)  invalFunction,
void(*)(void)  resetFunction 
)

Definition at line 71 of file sinval.c.

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

Referenced by AcceptInvalidationMessages().

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

Definition at line 49 of file sinval.c.

References SIInsertDataEntries().

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

50 {
51  SIInsertDataEntries(msgs, n);
52 }
void SIInsertDataEntries(const SharedInvalidationMessage *data, int n)
Definition: sinvaladt.c:436
int xactGetCommittedInvalidationMessages ( SharedInvalidationMessage **  msgs,
bool RelcacheInitFileInval 
)

Definition at line 816 of file inval.c.

References Assert, TransInvalidationInfo::CurrentCmdInvalidMsgs, CurTransactionContext, MakeSharedInvalidMessagesArray(), MemoryContextSwitchTo(), TransInvalidationInfo::my_level, 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 
856  SharedInvalidMessagesArray == NULL));
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 Assert(condition)
Definition: c.h:664

Variable Documentation

volatile sig_atomic_t catchupInterruptPending
uint64 SharedInvalidMessageCounter