Coverage Report

Created: 2026-10-16 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/include/access/multixact.h
Line
Count
Source
1
/*
2
 * multixact.h
3
 *
4
 * PostgreSQL multi-transaction-log manager
5
 *
6
 * Portions Copyright (c) 1996-2026, 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/transam.h"
15
#include "access/xlogreader.h"
16
#include "lib/stringinfo.h"
17
#include "storage/sync.h"
18
19
20
/*
21
 * The first two MultiXactId values are reserved to store the truncation Xid
22
 * and epoch of the first segment, so we start assigning multixact values from
23
 * 2.
24
 */
25
0
#define InvalidMultiXactId  ((MultiXactId) 0)
26
0
#define FirstMultiXactId  ((MultiXactId) 1)
27
0
#define MaxMultiXactId    ((MultiXactId) 0xFFFFFFFF)
28
29
0
#define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId)
30
31
/*
32
 * Decide which of two MultiXactIds is earlier.
33
 *
34
 * XXX do we need to do something special for InvalidMultiXactId?
35
 * (Doesn't look like it.)
36
 */
37
static inline bool
38
MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
39
0
{
40
0
  int32   diff = (int32) (multi1 - multi2);
41
42
0
  return (diff < 0);
43
0
}
Unexecuted instantiation: heapam.c:MultiXactIdPrecedes
Unexecuted instantiation: heapam_handler.c:MultiXactIdPrecedes
Unexecuted instantiation: heapam_visibility.c:MultiXactIdPrecedes
Unexecuted instantiation: pruneheap.c:MultiXactIdPrecedes
Unexecuted instantiation: vacuumlazy.c:MultiXactIdPrecedes
Unexecuted instantiation: mxactdesc.c:MultiXactIdPrecedes
Unexecuted instantiation: multixact.c:MultiXactIdPrecedes
Unexecuted instantiation: rmgr.c:MultiXactIdPrecedes
Unexecuted instantiation: twophase_rmgr.c:MultiXactIdPrecedes
Unexecuted instantiation: xact.c:MultiXactIdPrecedes
Unexecuted instantiation: xlog.c:MultiXactIdPrecedes
Unexecuted instantiation: heap.c:MultiXactIdPrecedes
Unexecuted instantiation: index.c:MultiXactIdPrecedes
Unexecuted instantiation: analyze.c:MultiXactIdPrecedes
Unexecuted instantiation: dbcommands.c:MultiXactIdPrecedes
Unexecuted instantiation: matview.c:MultiXactIdPrecedes
Unexecuted instantiation: repack.c:MultiXactIdPrecedes
Unexecuted instantiation: sequence.c:MultiXactIdPrecedes
Unexecuted instantiation: tablecmds.c:MultiXactIdPrecedes
Unexecuted instantiation: vacuum.c:MultiXactIdPrecedes
Unexecuted instantiation: autovacuum.c:MultiXactIdPrecedes
Unexecuted instantiation: sync.c:MultiXactIdPrecedes
Unexecuted instantiation: multixactfuncs.c:MultiXactIdPrecedes
Unexecuted instantiation: xid.c:MultiXactIdPrecedes
Unexecuted instantiation: relcache.c:MultiXactIdPrecedes
44
45
/*
46
 * MultiXactIdPrecedesOrEquals -- is multi1 logically <= multi2?
47
 *
48
 * XXX do we need to do something special for InvalidMultiXactId?
49
 * (Doesn't look like it.)
50
 */
51
static inline bool
52
MultiXactIdPrecedesOrEquals(MultiXactId multi1, MultiXactId multi2)
53
0
{
54
0
  int32   diff = (int32) (multi1 - multi2);
55
56
0
  return (diff <= 0);
57
0
}
Unexecuted instantiation: heapam.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: heapam_handler.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: heapam_visibility.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: pruneheap.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: vacuumlazy.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: mxactdesc.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: multixact.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: rmgr.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: twophase_rmgr.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: xact.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: xlog.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: heap.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: index.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: analyze.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: dbcommands.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: matview.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: repack.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: sequence.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: tablecmds.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: vacuum.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: autovacuum.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: sync.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: multixactfuncs.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: xid.c:MultiXactIdPrecedesOrEquals
Unexecuted instantiation: relcache.c:MultiXactIdPrecedesOrEquals
58
59
/*
60
 * Possible multixact lock modes ("status").  The first four modes are for
61
 * tuple locks (FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR UPDATE); the
62
 * next two are used for update and delete modes.
63
 */
64
typedef enum
65
{
66
  MultiXactStatusForKeyShare = 0x00,
67
  MultiXactStatusForShare = 0x01,
68
  MultiXactStatusForNoKeyUpdate = 0x02,
69
  MultiXactStatusForUpdate = 0x03,
70
  /* an update that doesn't touch "key" columns */
71
  MultiXactStatusNoKeyUpdate = 0x04,
72
  /* other updates, and delete */
73
  MultiXactStatusUpdate = 0x05,
74
} MultiXactStatus;
75
76
#define MaxMultiXactStatus MultiXactStatusUpdate
77
78
/* does a status value correspond to a tuple update? */
79
#define ISUPDATE_from_mxstatus(status) \
80
0
      ((status) > MultiXactStatusForUpdate)
81
82
83
typedef struct MultiXactMember
84
{
85
  TransactionId xid;
86
  MultiXactStatus status;
87
} MultiXactMember;
88
89
90
/* ----------------
91
 *    multixact-related XLOG entries
92
 * ----------------
93
 */
94
95
0
#define XLOG_MULTIXACT_ZERO_OFF_PAGE  0x00
96
0
#define XLOG_MULTIXACT_ZERO_MEM_PAGE  0x10
97
0
#define XLOG_MULTIXACT_CREATE_ID    0x20
98
0
#define XLOG_MULTIXACT_TRUNCATE_ID    0x30
99
100
typedef struct xl_multixact_create
101
{
102
  MultiXactId mid;      /* new MultiXact's ID */
103
  MultiXactOffset moff;   /* its starting offset in members file */
104
  int32   nmembers;   /* number of member XIDs */
105
  MultiXactMember members[FLEXIBLE_ARRAY_MEMBER];
106
} xl_multixact_create;
107
108
0
#define SizeOfMultiXactCreate (offsetof(xl_multixact_create, members))
109
110
typedef struct xl_multixact_truncate
111
{
112
  Oid     oldestMultiDB;
113
114
  /* truncate multixact offsets older than this */
115
  MultiXactId oldestMulti;
116
117
  /* truncate multixact members older than this */
118
  MultiXactOffset oldestOffset;
119
} xl_multixact_truncate;
120
121
0
#define SizeOfMultiXactTruncate (sizeof(xl_multixact_truncate))
122
123
124
extern MultiXactId MultiXactIdCreate(TransactionId xid1,
125
                   MultiXactStatus status1, TransactionId xid2,
126
                   MultiXactStatus status2);
127
extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid,
128
                   MultiXactStatus status);
129
extern MultiXactId MultiXactIdCreateFromMembers(int nmembers,
130
                        MultiXactMember *members);
131
132
extern MultiXactId ReadNextMultiXactId(void);
133
extern void ReadMultiXactIdRange(MultiXactId *oldest, MultiXactId *next);
134
extern bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly);
135
extern void MultiXactIdSetOldestMember(void);
136
extern int  GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members,
137
                  bool from_pgupgrade, bool isLockOnly);
138
extern void GetMultiXactInfo(uint32 *multixacts, MultiXactOffset *nextOffset,
139
               MultiXactId *oldestMultiXactId,
140
               MultiXactOffset *oldestOffset);
141
142
extern int  multixactoffsetssyncfiletag(const FileTag *ftag, char *path);
143
extern int  multixactmemberssyncfiletag(const FileTag *ftag, char *path);
144
145
extern void AtEOXact_MultiXact(void);
146
extern void AtPrepare_MultiXact(void);
147
extern void PostPrepare_MultiXact(FullTransactionId fxid);
148
149
extern void BootStrapMultiXact(void);
150
extern void StartupMultiXact(void);
151
extern void TrimMultiXact(void);
152
extern void SetMultiXactIdLimit(MultiXactId oldest_datminmxid,
153
                Oid oldest_datoid);
154
extern void MultiXactGetCheckptMulti(bool is_shutdown,
155
                   MultiXactId *nextMulti,
156
                   MultiXactOffset *nextMultiOffset,
157
                   MultiXactId *oldestMulti,
158
                   Oid *oldestMultiDB);
159
extern void CheckPointMultiXact(void);
160
extern MultiXactId GetOldestMultiXactId(void);
161
extern void TruncateMultiXact(MultiXactId newOldestMulti,
162
                Oid newOldestMultiDB);
163
extern void MultiXactSetNextMXact(MultiXactId nextMulti,
164
                  MultiXactOffset nextMultiOffset);
165
extern void MultiXactAdvanceNextMXact(MultiXactId minMulti,
166
                    MultiXactOffset minMultiOffset);
167
extern void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB);
168
extern int  MultiXactMemberFreezeThreshold(void);
169
170
extern void multixact_twophase_recover(FullTransactionId fxid, uint16 info,
171
                     void *recdata, uint32 len);
172
extern void multixact_twophase_postcommit(FullTransactionId fxid, uint16 info,
173
                      void *recdata, uint32 len);
174
extern void multixact_twophase_postabort(FullTransactionId fxid, uint16 info,
175
                     void *recdata, uint32 len);
176
177
extern void multixact_redo(XLogReaderState *record);
178
extern void multixact_desc(StringInfo buf, XLogReaderState *record);
179
extern const char *multixact_identify(uint8 info);
180
extern char *mxid_to_string(MultiXactId multi, int nmembers,
181
              MultiXactMember *members);
182
extern char *mxstatus_to_string(MultiXactStatus status);
183
184
#endif              /* MULTIXACT_H */