1 /*------------------------------------------------------------------------- 2 * 3 * sinval.h 4 * POSTGRES shared cache invalidation communication definitions. 5 * 6 * 7 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group 8 * Portions Copyright (c) 1994, Regents of the University of California 9 * 10 * src/include/storage/sinval.h 11 * 12 *------------------------------------------------------------------------- 13 */ 14 #ifndef SINVAL_H 15 #define SINVAL_H 16 17 #include <signal.h> 18 19 #include "storage/relfilenode.h" 20 21 /* 22 * We support several types of shared-invalidation messages: 23 * * invalidate a specific tuple in a specific catcache 24 * * invalidate all catcache entries from a given system catalog 25 * * invalidate a relcache entry for a specific logical relation 26 * * invalidate all relcache entries 27 * * invalidate an smgr cache entry for a specific physical relation 28 * * invalidate the mapped-relation mapping for a given database 29 * * invalidate any saved snapshot that might be used to scan a given relation 30 * More types could be added if needed. The message type is identified by 31 * the first "int8" field of the message struct. Zero or positive means a 32 * specific-catcache inval message (and also serves as the catcache ID field). 33 * Negative values identify the other message types, as per codes below. 34 * 35 * Catcache inval events are initially driven by detecting tuple inserts, 36 * updates and deletions in system catalogs (see CacheInvalidateHeapTuple). 37 * An update can generate two inval events, one for the old tuple and one for 38 * the new, but this is reduced to one event if the tuple's hash key doesn't 39 * change. Note that the inval events themselves don't actually say whether 40 * the tuple is being inserted or deleted. Also, since we transmit only a 41 * hash key, there is a small risk of unnecessary invalidations due to chance 42 * matches of hash keys. 43 * 44 * Note that some system catalogs have multiple caches on them (with different 45 * indexes). On detecting a tuple invalidation in such a catalog, separate 46 * catcache inval messages must be generated for each of its caches, since 47 * the hash keys will generally be different. 48 * 49 * Catcache, relcache, and snapshot invalidations are transactional, and so 50 * are sent to other backends upon commit. Internally to the generating 51 * backend, they are also processed at CommandCounterIncrement so that later 52 * commands in the same transaction see the new state. The generating backend 53 * also has to process them at abort, to flush out any cache state it's loaded 54 * from no-longer-valid entries. 55 * 56 * smgr and relation mapping invalidations are non-transactional: they are 57 * sent immediately when the underlying file change is made. 58 */ 59 60 typedef struct 61 { 62 int8 id; /* cache ID --- must be first */ 63 Oid dbId; /* database ID, or 0 if a shared relation */ 64 uint32 hashValue; /* hash value of key for this catcache */ 65 } SharedInvalCatcacheMsg; 66 67 #define SHAREDINVALCATALOG_ID (-1) 68 69 typedef struct 70 { 71 int8 id; /* type field --- must be first */ 72 Oid dbId; /* database ID, or 0 if a shared catalog */ 73 Oid catId; /* ID of catalog whose contents are invalid */ 74 } SharedInvalCatalogMsg; 75 76 #define SHAREDINVALRELCACHE_ID (-2) 77 78 typedef struct 79 { 80 int8 id; /* type field --- must be first */ 81 Oid dbId; /* database ID, or 0 if a shared relation */ 82 Oid relId; /* relation ID, or 0 if whole relcache */ 83 } SharedInvalRelcacheMsg; 84 85 #define SHAREDINVALSMGR_ID (-3) 86 87 typedef struct 88 { 89 /* note: field layout chosen to pack into 16 bytes */ 90 int8 id; /* type field --- must be first */ 91 int8 backend_hi; /* high bits of backend ID, if temprel */ 92 uint16 backend_lo; /* low bits of backend ID, if temprel */ 93 RelFileNode rnode; /* spcNode, dbNode, relNode */ 94 } SharedInvalSmgrMsg; 95 96 #define SHAREDINVALRELMAP_ID (-4) 97 98 typedef struct 99 { 100 int8 id; /* type field --- must be first */ 101 Oid dbId; /* database ID, or 0 for shared catalogs */ 102 } SharedInvalRelmapMsg; 103 104 #define SHAREDINVALSNAPSHOT_ID (-5) 105 106 typedef struct 107 { 108 int8 id; /* type field --- must be first */ 109 Oid dbId; /* database ID, or 0 if a shared relation */ 110 Oid relId; /* relation ID */ 111 } SharedInvalSnapshotMsg; 112 113 typedef union 114 { 115 int8 id; /* type field --- must be first */ 116 SharedInvalCatcacheMsg cc; 117 SharedInvalCatalogMsg cat; 118 SharedInvalRelcacheMsg rc; 119 SharedInvalSmgrMsg sm; 120 SharedInvalRelmapMsg rm; 121 SharedInvalSnapshotMsg sn; 122 } SharedInvalidationMessage; 123 124 125 /* Counter of messages processed; don't worry about overflow. */ 126 extern uint64 SharedInvalidMessageCounter; 127 128 extern volatile sig_atomic_t catchupInterruptPending; 129 130 extern void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, 131 int n); 132 extern void ReceiveSharedInvalidMessages( 133 void (*invalFunction) (SharedInvalidationMessage *msg), 134 void (*resetFunction) (void)); 135 136 /* signal handler for catchup events (PROCSIG_CATCHUP_INTERRUPT) */ 137 extern void HandleCatchupInterrupt(void); 138 139 /* 140 * enable/disable processing of catchup events directly from signal handler. 141 * The enable routine first performs processing of any catchup events that 142 * have occurred since the last disable. 143 */ 144 extern void ProcessCatchupInterrupt(void); 145 146 extern int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, 147 bool *RelcacheInitFileInval); 148 extern void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, 149 int nmsgs, bool RelcacheInitFileInval, 150 Oid dbid, Oid tsid); 151 152 extern void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg); 153 154 #endif /* SINVAL_H */ 155