PostgreSQL Source Code git master
multixact_rewrite.c File Reference
#include "postgres_fe.h"
#include "access/multixact_internal.h"
#include "multixact_read_v18.h"
#include "pg_upgrade.h"
Include dependency graph for multixact_rewrite.c:

Go to the source code of this file.

Functions

static void RecordMultiXactOffset (SlruSegState *offsets_writer, MultiXactId multi, MultiXactOffset offset)
 
static void RecordMultiXactMembers (SlruSegState *members_writer, MultiXactOffset offset, int nmembers, MultiXactMember *members)
 
MultiXactOffset rewrite_multixacts (MultiXactId from_multi, MultiXactId to_multi)
 

Function Documentation

◆ RecordMultiXactMembers()

static void RecordMultiXactMembers ( SlruSegState members_writer,
MultiXactOffset  offset,
int  nmembers,
MultiXactMember members 
)
static

Definition at line 156 of file multixact_rewrite.c.

159{
160 for (int i = 0; i < nmembers; i++, offset++)
161 {
162 int64 pageno;
163 char *buf;
164 TransactionId *memberptr;
165 uint32 *flagsptr;
166 uint32 flagsval;
167 int bshift;
168 int flagsoff;
169 int memberoff;
170
171 Assert(members[i].status <= MultiXactStatusUpdate);
172
173 pageno = MXOffsetToMemberPage(offset);
174 memberoff = MXOffsetToMemberOffset(offset);
175 flagsoff = MXOffsetToFlagsOffset(offset);
176 bshift = MXOffsetToFlagsBitShift(offset);
177
178 buf = SlruWriteSwitchPage(members_writer, pageno);
179
180 memberptr = (TransactionId *) (buf + memberoff);
181
182 *memberptr = members[i].xid;
183
184 flagsptr = (uint32 *) (buf + flagsoff);
185
186 flagsval = *flagsptr;
187 flagsval &= ~(((1 << MXACT_MEMBER_BITS_PER_XACT) - 1) << bshift);
188 flagsval |= (members[i].status << bshift);
189 *flagsptr = flagsval;
190 }
191}
int64_t int64
Definition: c.h:549
uint32_t uint32
Definition: c.h:552
uint32 TransactionId
Definition: c.h:671
Assert(PointerIsAligned(start, uint64))
int i
Definition: isn.c:77
@ MultiXactStatusUpdate
Definition: multixact.h:45
#define MXACT_MEMBER_BITS_PER_XACT
static int MXOffsetToFlagsBitShift(MultiXactOffset32 offset)
static int64 MXOffsetToMemberPage(MultiXactOffset32 offset)
static int MXOffsetToMemberOffset(MultiXactOffset32 offset)
static int MXOffsetToFlagsOffset(MultiXactOffset32 offset)
static char buf[DEFAULT_XLOG_SEG_SIZE]
Definition: pg_test_fsync.c:71
static char * SlruWriteSwitchPage(SlruSegState *state, uint64 pageno)
Definition: slru_io.h:45
TransactionId xid
Definition: multixact.h:57
MultiXactStatus status
Definition: multixact.h:58

References Assert(), buf, i, MultiXactStatusUpdate, MXACT_MEMBER_BITS_PER_XACT, MXOffsetToFlagsBitShift(), MXOffsetToFlagsOffset(), MXOffsetToMemberOffset(), MXOffsetToMemberPage(), SlruWriteSwitchPage(), MultiXactMember::status, and MultiXactMember::xid.

Referenced by rewrite_multixacts().

◆ RecordMultiXactOffset()

static void RecordMultiXactOffset ( SlruSegState offsets_writer,
MultiXactId  multi,
MultiXactOffset  offset 
)
static

Definition at line 134 of file multixact_rewrite.c.

136{
137 int64 pageno;
138 int entryno;
139 char *buf;
140 MultiXactOffset *offptr;
141
142 pageno = MultiXactIdToOffsetPage(multi);
143 entryno = MultiXactIdToOffsetEntry(multi);
144
145 buf = SlruWriteSwitchPage(offsets_writer, pageno);
146 offptr = (MultiXactOffset *) buf;
147 offptr[entryno] = offset;
148}
uint64 MultiXactOffset
Definition: c.h:683
static int MultiXactIdToOffsetEntry(MultiXactId multi)
static int64 MultiXactIdToOffsetPage(MultiXactId multi)

References buf, MultiXactIdToOffsetEntry(), MultiXactIdToOffsetPage(), and SlruWriteSwitchPage().

Referenced by rewrite_multixacts().

◆ rewrite_multixacts()

MultiXactOffset rewrite_multixacts ( MultiXactId  from_multi,
MultiXactId  to_multi 
)

Definition at line 38 of file multixact_rewrite.c.

39{
40 MultiXactOffset next_offset;
41 SlruSegState *offsets_writer;
42 SlruSegState *members_writer;
43 char dir[MAXPGPATH] = {0};
44 bool prev_multixid_valid = false;
45
46 /*
47 * The range of valid multi XIDs is unchanged by the conversion (they are
48 * referenced from the heap tables), but the members SLRU is rewritten to
49 * start from offset 1.
50 */
51 next_offset = 1;
52
53 /* Prepare to write the new SLRU files */
54 pg_sprintf(dir, "%s/pg_multixact/offsets", new_cluster.pgdata);
55 offsets_writer = AllocSlruWrite(dir, false);
56 SlruWriteSwitchPage(offsets_writer, MultiXactIdToOffsetPage(from_multi));
57
58 pg_sprintf(dir, "%s/pg_multixact/members", new_cluster.pgdata);
59 members_writer = AllocSlruWrite(dir, true /* use long segment names */ );
60 SlruWriteSwitchPage(members_writer, MXOffsetToMemberPage(next_offset));
61
62 /*
63 * Convert old multixids, if needed, by reading them one-by-one from the
64 * old cluster.
65 */
66 if (to_multi != from_multi)
67 {
68 OldMultiXactReader *old_reader;
69
73
74 for (MultiXactId multi = from_multi; multi != to_multi;)
75 {
76 MultiXactMember member;
77 bool multixid_valid;
78
79 /*
80 * Read this multixid's members.
81 *
82 * Locking-only XIDs that may be part of multi-xids don't matter
83 * after upgrade, as there can be no transactions running across
84 * upgrade. So as a small optimization, we only read one member
85 * from each multixid: the one updating one, or if there was no
86 * update, arbitrarily the first locking xid.
87 */
88 multixid_valid = GetOldMultiXactIdSingleMember(old_reader, multi, &member);
89
90 /*
91 * Write the new offset to pg_multixact/offsets.
92 *
93 * Even if this multixid is invalid, we still need to write its
94 * offset if the *previous* multixid was valid. That's because
95 * when reading a multixid, the number of members is calculated
96 * from the difference between the two offsets.
97 */
98 RecordMultiXactOffset(offsets_writer, multi,
99 (multixid_valid || prev_multixid_valid) ? next_offset : 0);
100
101 /* Write the members */
102 if (multixid_valid)
103 {
104 RecordMultiXactMembers(members_writer, next_offset, 1, &member);
105 next_offset += 1;
106 }
107
108 /* Advance to next multixid, handling wraparound */
109 multi++;
110 if (multi < FirstMultiXactId)
111 multi = FirstMultiXactId;
112 prev_multixid_valid = multixid_valid;
113 }
114
115 FreeOldMultiXactReader(old_reader);
116 }
117
118 /* Write the final 'next' offset to the last SLRU page */
119 RecordMultiXactOffset(offsets_writer, to_multi,
120 prev_multixid_valid ? next_offset : 0);
121
122 /* Flush the last SLRU pages */
123 FreeSlruWrite(offsets_writer);
124 FreeSlruWrite(members_writer);
125
126 return next_offset;
127}
TransactionId MultiXactId
Definition: c.h:681
#define FirstMultiXactId
Definition: multixact.h:26
bool GetOldMultiXactIdSingleMember(OldMultiXactReader *state, MultiXactId multi, MultiXactMember *member)
OldMultiXactReader * AllocOldMultiXactRead(char *pgdata, MultiXactId nextMulti, MultiXactOffset32 nextOffset)
void FreeOldMultiXactReader(OldMultiXactReader *state)
static void RecordMultiXactOffset(SlruSegState *offsets_writer, MultiXactId multi, MultiXactOffset offset)
static void RecordMultiXactMembers(SlruSegState *members_writer, MultiXactOffset offset, int nmembers, MultiXactMember *members)
#define MAXPGPATH
ClusterInfo new_cluster
Definition: pg_upgrade.c:74
ClusterInfo old_cluster
Definition: pg_upgrade.c:73
int int int int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2
void FreeSlruWrite(SlruSegState *state)
Definition: slru_io.c:260
SlruSegState * AllocSlruWrite(const char *dir, bool long_segment_names)
Definition: slru_io.c:166
char * pgdata
Definition: pg_upgrade.h:299
ControlData controldata
Definition: pg_upgrade.h:296
uint32 chkpnt_nxtmulti
Definition: pg_upgrade.h:244
uint64 chkpnt_nxtmxoff
Definition: pg_upgrade.h:245

References AllocOldMultiXactRead(), AllocSlruWrite(), ControlData::chkpnt_nxtmulti, ControlData::chkpnt_nxtmxoff, ClusterInfo::controldata, FirstMultiXactId, FreeOldMultiXactReader(), FreeSlruWrite(), GetOldMultiXactIdSingleMember(), MAXPGPATH, MultiXactIdToOffsetPage(), MXOffsetToMemberPage(), new_cluster, old_cluster, pg_sprintf(), ClusterInfo::pgdata, RecordMultiXactMembers(), RecordMultiXactOffset(), and SlruWriteSwitchPage().

Referenced by copy_xact_xlog_xid().