1/*
2 * multixact.h
3 *
4 * PostgreSQL multi-transaction-log manager
5 *
6 * Portions Copyright (c) 1996-2019, 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 */
40typedef 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
59typedef 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
76typedef 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
86typedef 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
102extern MultiXactId MultiXactIdCreate(TransactionId xid1,
103 MultiXactStatus status1, TransactionId xid2,
104 MultiXactStatus status2);
105extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid,
106 MultiXactStatus status);
107extern MultiXactId MultiXactIdCreateFromMembers(int nmembers,
108 MultiXactMember *members);
109
110extern MultiXactId ReadNextMultiXactId(void);
111extern bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly);
112extern void MultiXactIdSetOldestMember(void);
113extern int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **xids,
114 bool allow_old, bool isLockOnly);
115extern bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2);
116extern bool MultiXactIdPrecedesOrEquals(MultiXactId multi1,
117 MultiXactId multi2);
118
119extern void AtEOXact_MultiXact(void);
120extern void AtPrepare_MultiXact(void);
121extern void PostPrepare_MultiXact(TransactionId xid);
122
123extern Size MultiXactShmemSize(void);
124extern void MultiXactShmemInit(void);
125extern void BootStrapMultiXact(void);
126extern void StartupMultiXact(void);
127extern void TrimMultiXact(void);
128extern void ShutdownMultiXact(void);
129extern void SetMultiXactIdLimit(MultiXactId oldest_datminmxid,
130 Oid oldest_datoid,
131 bool is_startup);
132extern void MultiXactGetCheckptMulti(bool is_shutdown,
133 MultiXactId *nextMulti,
134 MultiXactOffset *nextMultiOffset,
135 MultiXactId *oldestMulti,
136 Oid *oldestMultiDB);
137extern void CheckPointMultiXact(void);
138extern MultiXactId GetOldestMultiXactId(void);
139extern void TruncateMultiXact(MultiXactId oldestMulti, Oid oldestMultiDB);
140extern void MultiXactSetNextMXact(MultiXactId nextMulti,
141 MultiXactOffset nextMultiOffset);
142extern void MultiXactAdvanceNextMXact(MultiXactId minMulti,
143 MultiXactOffset minMultiOffset);
144extern void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB);
145extern int MultiXactMemberFreezeThreshold(void);
146
147extern void multixact_twophase_recover(TransactionId xid, uint16 info,
148 void *recdata, uint32 len);
149extern void multixact_twophase_postcommit(TransactionId xid, uint16 info,
150 void *recdata, uint32 len);
151extern void multixact_twophase_postabort(TransactionId xid, uint16 info,
152 void *recdata, uint32 len);
153
154extern void multixact_redo(XLogReaderState *record);
155extern void multixact_desc(StringInfo buf, XLogReaderState *record);
156extern const char *multixact_identify(uint8 info);
157extern char *mxid_to_string(MultiXactId multi, int nmembers,
158 MultiXactMember *members);
159
160#endif /* MULTIXACT_H */
161