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