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