PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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
 
struct  SharedInvalRelSyncMsg
 
union  SharedInvalidationMessage
 

Macros

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

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 68 of file sinval.h.

◆ SHAREDINVALRELCACHE_ID

#define SHAREDINVALRELCACHE_ID   (-2)

Definition at line 77 of file sinval.h.

◆ SHAREDINVALRELMAP_ID

#define SHAREDINVALRELMAP_ID   (-4)

Definition at line 97 of file sinval.h.

◆ SHAREDINVALRELSYNC_ID

#define SHAREDINVALRELSYNC_ID   (-6)

Definition at line 114 of file sinval.h.

◆ SHAREDINVALSMGR_ID

#define SHAREDINVALSMGR_ID   (-3)

Definition at line 86 of file sinval.h.

◆ SHAREDINVALSNAPSHOT_ID

#define SHAREDINVALSNAPSHOT_ID   (-5)

Definition at line 105 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 */
165}
struct Latch * MyLatch
Definition: globals.c:64
void SetLatch(Latch *latch)
Definition: latch.c:288
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 1088 of file inval.c.

1090{
1091 SharedInvalidationMessage *msgarray;
1092 int nummsgs;
1093 int nmsgs;
1094
1095 /* Quick exit if we haven't done anything with invalidation messages. */
1096 if (inplaceInvalInfo == NULL)
1097 {
1098 *RelcacheInitFileInval = false;
1099 *msgs = NULL;
1100 return 0;
1101 }
1102
1103 *RelcacheInitFileInval = inplaceInvalInfo->RelcacheInitFileInval;
1105 *msgs = msgarray = (SharedInvalidationMessage *)
1106 palloc(nummsgs * sizeof(SharedInvalidationMessage));
1107
1108 nmsgs = 0;
1111 (memcpy(msgarray + nmsgs,
1112 msgs,
1113 n * sizeof(SharedInvalidationMessage)),
1114 nmsgs += n));
1117 (memcpy(msgarray + nmsgs,
1118 msgs,
1119 n * sizeof(SharedInvalidationMessage)),
1120 nmsgs += n));
1121 Assert(nmsgs == nummsgs);
1122
1123 return nmsgs;
1124}
Assert(PointerIsAligned(start, uint64))
#define NumMessagesInGroup(group)
Definition: inval.c:207
#define CatCacheMsgs
Definition: inval.c:171
#define ProcessMessageSubGroupMulti(group, subgroup, codeFragment)
Definition: inval.c:402
static InvalidationInfo * inplaceInvalInfo
Definition: inval.c:257
#define RelCacheMsgs
Definition: inval.c:172
void * palloc(Size size)
Definition: mcxt.c:1940
bool RelcacheInitFileInval
Definition: inval.c:236
InvalidationMsgsGroup CurrentCmdInvalidMsgs
Definition: inval.c:233

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 823 of file inval.c.

824{
825 if (msg->id >= 0)
826 {
827 if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid)
828 {
830
831 SysCacheInvalidate(msg->cc.id, msg->cc.hashValue);
832
834 }
835 }
836 else if (msg->id == SHAREDINVALCATALOG_ID)
837 {
838 if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid)
839 {
841
843
844 /* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */
845 }
846 }
847 else if (msg->id == SHAREDINVALRELCACHE_ID)
848 {
849 if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid)
850 {
851 int i;
852
853 if (msg->rc.relId == InvalidOid)
855 else
857
858 for (i = 0; i < relcache_callback_count; i++)
859 {
860 struct RELCACHECALLBACK *ccitem = relcache_callback_list + i;
861
862 ccitem->function(ccitem->arg, msg->rc.relId);
863 }
864 }
865 }
866 else if (msg->id == SHAREDINVALSMGR_ID)
867 {
868 /*
869 * We could have smgr entries for relations of other databases, so no
870 * short-circuit test is possible here.
871 */
872 RelFileLocatorBackend rlocator;
873
874 rlocator.locator = msg->sm.rlocator;
875 rlocator.backend = (msg->sm.backend_hi << 16) | (int) msg->sm.backend_lo;
876 smgrreleaserellocator(rlocator);
877 }
878 else if (msg->id == SHAREDINVALRELMAP_ID)
879 {
880 /* We only care about our own database and shared catalogs */
881 if (msg->rm.dbId == InvalidOid)
883 else if (msg->rm.dbId == MyDatabaseId)
885 }
886 else if (msg->id == SHAREDINVALSNAPSHOT_ID)
887 {
888 /* We only care about our own database and shared catalogs */
889 if (msg->sn.dbId == InvalidOid)
891 else if (msg->sn.dbId == MyDatabaseId)
893 }
894 else if (msg->id == SHAREDINVALRELSYNC_ID)
895 {
896 /* We only care about our own database */
897 if (msg->rs.dbId == MyDatabaseId)
899 }
900 else
901 elog(FATAL, "unrecognized SI message ID: %d", msg->id);
902}
void CatalogCacheFlushCatalog(Oid catId)
Definition: catcache.c:834
#define FATAL
Definition: elog.h:41
#define elog(elevel,...)
Definition: elog.h:226
Oid MyDatabaseId
Definition: globals.c:95
void CallRelSyncCallbacks(Oid relid)
Definition: inval.c:1916
static int relcache_callback_count
Definition: inval.c:294
static struct RELCACHECALLBACK relcache_callback_list[MAX_RELCACHE_CALLBACKS]
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1894
int i
Definition: isn.c:77
#define InvalidOid
Definition: postgres_ext.h:35
void RelationCacheInvalidate(bool debug_discard)
Definition: relcache.c:2994
void RelationCacheInvalidateEntry(Oid relationId)
Definition: relcache.c:2938
void RelationMapInvalidate(bool shared)
Definition: relmapper.c:468
#define SHAREDINVALCATALOG_ID
Definition: sinval.h:68
#define SHAREDINVALRELSYNC_ID
Definition: sinval.h:114
#define SHAREDINVALSMGR_ID
Definition: sinval.h:86
#define SHAREDINVALSNAPSHOT_ID
Definition: sinval.h:105
#define SHAREDINVALRELCACHE_ID
Definition: sinval.h:77
#define SHAREDINVALRELMAP_ID
Definition: sinval.h:97
void smgrreleaserellocator(RelFileLocatorBackend rlocator)
Definition: smgr.c:443
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:443
RelcacheCallbackFunction function
Definition: inval.c:290
RelFileLocator locator
uint16 backend_lo
Definition: sinval.h:93
RelFileLocator rlocator
Definition: sinval.h:94
void SysCacheInvalidate(int cacheId, uint32 hashValue)
Definition: syscache.c:698
SharedInvalCatcacheMsg cc
Definition: sinval.h:127
SharedInvalRelcacheMsg rc
Definition: sinval.h:129
SharedInvalCatalogMsg cat
Definition: sinval.h:128
SharedInvalRelSyncMsg rs
Definition: sinval.h:133
SharedInvalSmgrMsg sm
Definition: sinval.h:130
SharedInvalSnapshotMsg sn
Definition: sinval.h:132
SharedInvalRelmapMsg rm
Definition: sinval.h:131

References RELCACHECALLBACK::arg, RelFileLocatorBackend::backend, SharedInvalSmgrMsg::backend_hi, SharedInvalSmgrMsg::backend_lo, CallRelSyncCallbacks(), CallSyscacheCallbacks(), SharedInvalidationMessage::cat, CatalogCacheFlushCatalog(), SharedInvalCatalogMsg::catId, SharedInvalidationMessage::cc, SharedInvalCatcacheMsg::dbId, SharedInvalCatalogMsg::dbId, SharedInvalRelcacheMsg::dbId, SharedInvalRelmapMsg::dbId, SharedInvalSnapshotMsg::dbId, SharedInvalRelSyncMsg::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, SharedInvalRelSyncMsg::relid, SharedInvalSmgrMsg::rlocator, SharedInvalidationMessage::rm, SharedInvalidationMessage::rs, SHAREDINVALCATALOG_ID, SHAREDINVALRELCACHE_ID, SHAREDINVALRELMAP_ID, SHAREDINVALRELSYNC_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:930
bool IsTransactionOrTransactionBlock(void)
Definition: xact.c:4989
void StartTransactionCommand(void)
Definition: xact.c:3059
void CommitTransactionCommand(void)
Definition: xact.c:3157

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

Referenced by ProcessAutoVacLauncherInterrupts(), and ProcessClientReadInterrupt().

◆ ProcessCommittedInvalidationMessages()

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

Definition at line 1135 of file inval.c.

1138{
1139 if (nmsgs <= 0)
1140 return;
1141
1142 elog(DEBUG4, "replaying commit with %d messages%s", nmsgs,
1143 (RelcacheInitFileInval ? " and relcache file invalidation" : ""));
1144
1145 if (RelcacheInitFileInval)
1146 {
1147 elog(DEBUG4, "removing relcache init files for database %u", dbid);
1148
1149 /*
1150 * RelationCacheInitFilePreInvalidate, when the invalidation message
1151 * is for a specific database, requires DatabasePath to be set, but we
1152 * should not use SetDatabasePath during recovery, since it is
1153 * intended to be used only once by normal backends. Hence, a quick
1154 * hack: set DatabasePath directly then unset after use.
1155 */
1156 if (OidIsValid(dbid))
1157 DatabasePath = GetDatabasePath(dbid, tsid);
1158
1160
1161 if (OidIsValid(dbid))
1162 {
1164 DatabasePath = NULL;
1165 }
1166 }
1167
1168 SendSharedInvalidMessages(msgs, nmsgs);
1169
1170 if (RelcacheInitFileInval)
1172}
#define OidIsValid(objectId)
Definition: c.h:746
char * DatabasePath
Definition: globals.c:105
void pfree(void *pointer)
Definition: mcxt.c:2147
void RelationCacheInitFilePostInvalidate(void)
Definition: relcache.c:6882
void RelationCacheInitFilePreInvalidate(void)
Definition: relcache.c:6857
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
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 {
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 1012 of file inval.c.

1014{
1015 SharedInvalidationMessage *msgarray;
1016 int nummsgs;
1017 int nmsgs;
1018
1019 /* Quick exit if we haven't done anything with invalidation messages. */
1020 if (transInvalInfo == NULL)
1021 {
1022 *RelcacheInitFileInval = false;
1023 *msgs = NULL;
1024 return 0;
1025 }
1026
1027 /* Must be at top of stack */
1029
1030 /*
1031 * Relcache init file invalidation requires processing both before and
1032 * after we send the SI messages. However, we need not do anything unless
1033 * we committed.
1034 */
1035 *RelcacheInitFileInval = transInvalInfo->ii.RelcacheInitFileInval;
1036
1037 /*
1038 * Collect all the pending messages into a single contiguous array of
1039 * invalidation messages, to simplify what needs to happen while building
1040 * the commit WAL message. Maintain the order that they would be
1041 * processed in by AtEOXact_Inval(), to ensure emulated behaviour in redo
1042 * is as similar as possible to original. We want the same bugs, if any,
1043 * not new ones.
1044 */
1047
1048 *msgs = msgarray = (SharedInvalidationMessage *)
1050 nummsgs * sizeof(SharedInvalidationMessage));
1051
1052 nmsgs = 0;
1055 (memcpy(msgarray + nmsgs,
1056 msgs,
1057 n * sizeof(SharedInvalidationMessage)),
1058 nmsgs += n));
1061 (memcpy(msgarray + nmsgs,
1062 msgs,
1063 n * sizeof(SharedInvalidationMessage)),
1064 nmsgs += n));
1067 (memcpy(msgarray + nmsgs,
1068 msgs,
1069 n * sizeof(SharedInvalidationMessage)),
1070 nmsgs += n));
1073 (memcpy(msgarray + nmsgs,
1074 msgs,
1075 n * sizeof(SharedInvalidationMessage)),
1076 nmsgs += n));
1077 Assert(nmsgs == nummsgs);
1078
1079 return nmsgs;
1080}
static TransInvalidationInfo * transInvalInfo
Definition: inval.c:255
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1256
MemoryContext CurTransactionContext
Definition: mcxt.c:171
struct TransInvalidationInfo * parent
Definition: inval.c:249
struct InvalidationInfo ii
Definition: inval.c:243
InvalidationMsgsGroup PriorCmdInvalidMsgs
Definition: inval.c:246

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