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