1 /*
2  * multixact.h
3  *
4  * PostgreSQL multi-transaction-log manager
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * src/include/access/multixact.h
10  */
11 #ifndef MULTIXACT_H
12 #define MULTIXACT_H
13 
14 #include "access/xlogreader.h"
15 #include "lib/stringinfo.h"
16 
17 
18 /*
19  * The first two MultiXactId values are reserved to store the truncation Xid
20  * and epoch of the first segment, so we start assigning multixact values from
21  * 2.
22  */
23 #define InvalidMultiXactId	((MultiXactId) 0)
24 #define FirstMultiXactId	((MultiXactId) 1)
25 #define MaxMultiXactId		((MultiXactId) 0xFFFFFFFF)
26 
27 #define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId)
28 
29 #define MaxMultiXactOffset	((MultiXactOffset) 0xFFFFFFFF)
30 
31 /* Number of SLRU buffers to use for multixact */
32 #define NUM_MXACTOFFSET_BUFFERS		8
33 #define NUM_MXACTMEMBER_BUFFERS		16
34 
35 /*
36  * Possible multixact lock modes ("status").  The first four modes are for
37  * tuple locks (FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR UPDATE); the
38  * next two are used for update and delete modes.
39  */
40 typedef enum
41 {
42 	MultiXactStatusForKeyShare = 0x00,
43 	MultiXactStatusForShare = 0x01,
44 	MultiXactStatusForNoKeyUpdate = 0x02,
45 	MultiXactStatusForUpdate = 0x03,
46 	/* an update that doesn't touch "key" columns */
47 	MultiXactStatusNoKeyUpdate = 0x04,
48 	/* other updates, and delete */
49 	MultiXactStatusUpdate = 0x05
50 } MultiXactStatus;
51 
52 #define MaxMultiXactStatus MultiXactStatusUpdate
53 
54 /* does a status value correspond to a tuple update? */
55 #define ISUPDATE_from_mxstatus(status) \
56 			((status) > MultiXactStatusForUpdate)
57 
58 
59 typedef struct MultiXactMember
60 {
61 	TransactionId xid;
62 	MultiXactStatus status;
63 } MultiXactMember;
64 
65 
66 /* ----------------
67  *		multixact-related XLOG entries
68  * ----------------
69  */
70 
71 #define XLOG_MULTIXACT_ZERO_OFF_PAGE	0x00
72 #define XLOG_MULTIXACT_ZERO_MEM_PAGE	0x10
73 #define XLOG_MULTIXACT_CREATE_ID		0x20
74 #define XLOG_MULTIXACT_TRUNCATE_ID		0x30
75 
76 typedef struct xl_multixact_create
77 {
78 	MultiXactId mid;			/* new MultiXact's ID */
79 	MultiXactOffset moff;		/* its starting offset in members file */
80 	int32		nmembers;		/* number of member XIDs */
81 	MultiXactMember members[FLEXIBLE_ARRAY_MEMBER];
82 } xl_multixact_create;
83 
84 #define SizeOfMultiXactCreate (offsetof(xl_multixact_create, members))
85 
86 typedef struct xl_multixact_truncate
87 {
88 	Oid			oldestMultiDB;
89 
90 	/* to-be-truncated range of multixact offsets */
91 	MultiXactId startTruncOff;	/* just for completeness' sake */
92 	MultiXactId endTruncOff;
93 
94 	/* to-be-truncated range of multixact members */
95 	MultiXactOffset startTruncMemb;
96 	MultiXactOffset endTruncMemb;
97 } xl_multixact_truncate;
98 
99 #define SizeOfMultiXactTruncate (sizeof(xl_multixact_truncate))
100 
101 
102 extern MultiXactId MultiXactIdCreate(TransactionId xid1,
103 				  MultiXactStatus status1, TransactionId xid2,
104 				  MultiXactStatus status2);
105 extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid,
106 				  MultiXactStatus status);
107 extern MultiXactId MultiXactIdCreateFromMembers(int nmembers,
108 							 MultiXactMember *members);
109 
110 extern MultiXactId ReadNextMultiXactId(void);
111 extern bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly);
112 extern void MultiXactIdSetOldestMember(void);
113 extern int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **xids,
114 					  bool allow_old, bool isLockOnly);
115 extern bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2);
116 extern bool MultiXactIdPrecedesOrEquals(MultiXactId multi1,
117 							MultiXactId multi2);
118 
119 extern void AtEOXact_MultiXact(void);
120 extern void AtPrepare_MultiXact(void);
121 extern void PostPrepare_MultiXact(TransactionId xid);
122 
123 extern Size MultiXactShmemSize(void);
124 extern void MultiXactShmemInit(void);
125 extern void BootStrapMultiXact(void);
126 extern void StartupMultiXact(void);
127 extern void TrimMultiXact(void);
128 extern void ShutdownMultiXact(void);
129 extern void SetMultiXactIdLimit(MultiXactId oldest_datminmxid,
130 					Oid oldest_datoid,
131 					bool is_startup);
132 extern void MultiXactGetCheckptMulti(bool is_shutdown,
133 						 MultiXactId *nextMulti,
134 						 MultiXactOffset *nextMultiOffset,
135 						 MultiXactId *oldestMulti,
136 						 Oid *oldestMultiDB);
137 extern void CheckPointMultiXact(void);
138 extern MultiXactId GetOldestMultiXactId(void);
139 extern void TruncateMultiXact(MultiXactId oldestMulti, Oid oldestMultiDB);
140 extern void MultiXactSetNextMXact(MultiXactId nextMulti,
141 					  MultiXactOffset nextMultiOffset);
142 extern void MultiXactAdvanceNextMXact(MultiXactId minMulti,
143 						  MultiXactOffset minMultiOffset);
144 extern void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB);
145 extern int	MultiXactMemberFreezeThreshold(void);
146 
147 extern void multixact_twophase_recover(TransactionId xid, uint16 info,
148 						   void *recdata, uint32 len);
149 extern void multixact_twophase_postcommit(TransactionId xid, uint16 info,
150 							  void *recdata, uint32 len);
151 extern void multixact_twophase_postabort(TransactionId xid, uint16 info,
152 							 void *recdata, uint32 len);
153 
154 extern void multixact_redo(XLogReaderState *record);
155 extern void multixact_desc(StringInfo buf, XLogReaderState *record);
156 extern const char *multixact_identify(uint8 info);
157 extern char *mxid_to_string(MultiXactId multi, int nmembers,
158 			   MultiXactMember *members);
159 
160 #endif							/* MULTIXACT_H */
161