PostgreSQL Source Code git master
multixact_read_v18.h File Reference
#include "access/multixact.h"
#include "slru_io.h"
Include dependency graph for multixact_read_v18.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  OldMultiXactReader
 

Typedefs

typedef uint32 MultiXactOffset32
 
typedef struct OldMultiXactReader OldMultiXactReader
 

Functions

OldMultiXactReaderAllocOldMultiXactRead (char *pgdata, MultiXactId nextMulti, MultiXactOffset32 nextOffset)
 
bool GetOldMultiXactIdSingleMember (OldMultiXactReader *state, MultiXactId multi, MultiXactMember *member)
 
void FreeOldMultiXactReader (OldMultiXactReader *reader)
 

Typedef Documentation

◆ MultiXactOffset32

Definition at line 18 of file multixact_read_v18.h.

◆ OldMultiXactReader

Function Documentation

◆ AllocOldMultiXactRead()

OldMultiXactReader * AllocOldMultiXactRead ( char *  pgdata,
MultiXactId  nextMulti,
MultiXactOffset32  nextOffset 
)

Definition at line 119 of file multixact_read_v18.c.

121{
123 char dir[MAXPGPATH] = {0};
124
125 state->nextMXact = nextMulti;
126 state->nextOffset = nextOffset;
127
128 pg_sprintf(dir, "%s/pg_multixact/offsets", pgdata);
129 state->offset = AllocSlruRead(dir, false);
130
131 pg_sprintf(dir, "%s/pg_multixact/members", pgdata);
132 state->members = AllocSlruRead(dir, false);
133
134 return state;
135}
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define MAXPGPATH
int int int int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2
SlruSegState * AllocSlruRead(const char *dir, bool long_segment_names)
Definition: slru_io.c:62
Definition: regguts.h:323

References AllocSlruRead(), MAXPGPATH, pg_malloc(), and pg_sprintf().

Referenced by rewrite_multixacts().

◆ FreeOldMultiXactReader()

void FreeOldMultiXactReader ( OldMultiXactReader reader)

Definition at line 334 of file multixact_read_v18.c.

335{
336 FreeSlruRead(state->offset);
337 FreeSlruRead(state->members);
338
339 pfree(state);
340}
void pfree(void *pointer)
Definition: mcxt.c:1594
void FreeSlruRead(SlruSegState *state)
Definition: slru_io.c:153

References FreeSlruRead(), and pfree().

Referenced by rewrite_multixacts().

◆ GetOldMultiXactIdSingleMember()

bool GetOldMultiXactIdSingleMember ( OldMultiXactReader state,
MultiXactId  multi,
MultiXactMember member 
)

Definition at line 158 of file multixact_read_v18.c.

160{
161 MultiXactId nextMXact,
162 nextOffset,
163 tmpMXact;
164 int64 pageno,
165 prev_pageno;
166 int entryno,
167 length;
168 char *buf;
169 MultiXactOffset32 *offptr,
170 offset;
171 MultiXactOffset32 nextMXOffset;
173 MultiXactStatus result_status = 0;
174
175 nextMXact = state->nextMXact;
176 nextOffset = state->nextOffset;
177
178 /*
179 * Comment copied from GetMultiXactIdMembers in PostgreSQL v18
180 * multixact.c:
181 *
182 * Find out the offset at which we need to start reading MultiXactMembers
183 * and the number of members in the multixact. We determine the latter as
184 * the difference between this multixact's starting offset and the next
185 * one's. However, there are some corner cases to worry about:
186 *
187 * 1. This multixact may be the latest one created, in which case there is
188 * no next one to look at. The next multixact's offset should be set
189 * already, as we set it in RecordNewMultiXact(), but we used to not do
190 * that in older minor versions. To cope with that case, if this
191 * multixact is the latest one created, use the nextOffset value we read
192 * above as the endpoint.
193 *
194 * 2. Because GetNewMultiXactId skips over offset zero, to reserve zero
195 * for to mean "unset", there is an ambiguity near the point of offset
196 * wraparound. If we see next multixact's offset is one, is that our
197 * multixact's actual endpoint, or did it end at zero with a subsequent
198 * increment? We handle this using the knowledge that if the zero'th
199 * member slot wasn't filled, it'll contain zero, and zero isn't a valid
200 * transaction ID so it can't be a multixact member. Therefore, if we
201 * read a zero from the members array, just ignore it.
202 */
203
204 pageno = MultiXactIdToOffsetPage(multi);
205 entryno = MultiXactIdToOffsetEntry(multi);
206
207 buf = SlruReadSwitchPage(state->offset, pageno);
208 offptr = (MultiXactOffset32 *) buf;
209 offptr += entryno;
210 offset = *offptr;
211
212 if (offset == 0)
213 {
214 /* Invalid entry */
215 return false;
216 }
217
218 /*
219 * Use the same increment rule as GetNewMultiXactId(), that is, don't
220 * handle wraparound explicitly until needed.
221 */
222 tmpMXact = multi + 1;
223
224 if (nextMXact == tmpMXact)
225 {
226 /* Corner case 1: there is no next multixact */
227 nextMXOffset = nextOffset;
228 }
229 else
230 {
231 /* handle wraparound if needed */
232 if (tmpMXact < FirstMultiXactId)
233 tmpMXact = FirstMultiXactId;
234
235 prev_pageno = pageno;
236
237 pageno = MultiXactIdToOffsetPage(tmpMXact);
238 entryno = MultiXactIdToOffsetEntry(tmpMXact);
239
240 if (pageno != prev_pageno)
241 buf = SlruReadSwitchPage(state->offset, pageno);
242
243 offptr = (MultiXactOffset32 *) buf;
244 offptr += entryno;
245 nextMXOffset = *offptr;
246 }
247
248 if (nextMXOffset == 0)
249 {
250 /* Invalid entry */
251 return false;
252 }
253 length = nextMXOffset - offset;
254
255 /* read the members */
256 prev_pageno = -1;
257 for (int i = 0; i < length; i++, offset++)
258 {
259 TransactionId *xactptr;
260 uint32 *flagsptr;
261 int flagsoff;
262 int bshift;
263 int memberoff;
264 MultiXactStatus status;
265
266 pageno = MXOffsetToMemberPage(offset);
267 memberoff = MXOffsetToMemberOffset(offset);
268
269 if (pageno != prev_pageno)
270 {
271 buf = SlruReadSwitchPage(state->members, pageno);
272 prev_pageno = pageno;
273 }
274
275 xactptr = (TransactionId *) (buf + memberoff);
276 if (!TransactionIdIsValid(*xactptr))
277 {
278 /*
279 * Corner case 2: we are looking at unused slot zero
280 */
281 if (offset == 0)
282 continue;
283
284 /*
285 * Otherwise this is an invalid entry that should not be
286 * referenced from anywhere in the heap. We could return 'false'
287 * here, but we prefer to continue reading the members and
288 * converting them the best we can, to preserve evidence in case
289 * this is corruption that should not happen.
290 */
291 }
292
293 flagsoff = MXOffsetToFlagsOffset(offset);
294 bshift = MXOffsetToFlagsBitShift(offset);
295 flagsptr = (uint32 *) (buf + flagsoff);
296
297 status = (*flagsptr >> bshift) & MXACT_MEMBER_XACT_BITMASK;
298
299 /*
300 * Remember the updating XID among the members, or first locking XID
301 * if no updating XID.
302 */
303 if (ISUPDATE_from_mxstatus(status))
304 {
305 /* sanity check */
306 if (ISUPDATE_from_mxstatus(result_status))
307 {
308 /*
309 * We don't expect to see more than one updating member, even
310 * if the server had crashed.
311 */
312 pg_fatal("multixact %u has more than one updating member",
313 multi);
314 }
315 result_xid = *xactptr;
316 result_status = status;
317 }
318 else if (!TransactionIdIsValid(result_xid))
319 {
320 result_xid = *xactptr;
321 result_status = status;
322 }
323 }
324
325 member->xid = result_xid;
326 member->status = result_status;
327 return true;
328}
int64_t int64
Definition: c.h:549
TransactionId MultiXactId
Definition: c.h:681
uint32_t uint32
Definition: c.h:552
uint32 TransactionId
Definition: c.h:671
int i
Definition: isn.c:77
#define FirstMultiXactId
Definition: multixact.h:26
MultiXactStatus
Definition: multixact.h:37
#define ISUPDATE_from_mxstatus(status)
Definition: multixact.h:51
static int MXOffsetToFlagsBitShift(MultiXactOffset32 offset)
#define MXACT_MEMBER_XACT_BITMASK
static int64 MXOffsetToMemberPage(MultiXactOffset32 offset)
static int MXOffsetToMemberOffset(MultiXactOffset32 offset)
static int MultiXactIdToOffsetEntry(MultiXactId multi)
static int64 MultiXactIdToOffsetPage(MultiXactId multi)
static int MXOffsetToFlagsOffset(MultiXactOffset32 offset)
uint32 MultiXactOffset32
#define pg_fatal(...)
static char buf[DEFAULT_XLOG_SEG_SIZE]
Definition: pg_test_fsync.c:71
static char * SlruReadSwitchPage(SlruSegState *state, uint64 pageno)
Definition: slru_io.h:33
TransactionId xid
Definition: multixact.h:57
MultiXactStatus status
Definition: multixact.h:58
#define InvalidTransactionId
Definition: transam.h:31
#define TransactionIdIsValid(xid)
Definition: transam.h:41

References buf, FirstMultiXactId, i, InvalidTransactionId, ISUPDATE_from_mxstatus, MultiXactIdToOffsetEntry(), MultiXactIdToOffsetPage(), MXACT_MEMBER_XACT_BITMASK, MXOffsetToFlagsBitShift(), MXOffsetToFlagsOffset(), MXOffsetToMemberOffset(), MXOffsetToMemberPage(), pg_fatal, SlruReadSwitchPage(), MultiXactMember::status, TransactionIdIsValid, and MultiXactMember::xid.

Referenced by rewrite_multixacts().