PostgreSQL Source Code git master
xlogdesc.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * xlogdesc.c
4 * rmgr descriptor routines for access/transam/xlog.c
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/access/rmgrdesc/xlogdesc.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#include "access/transam.h"
18#include "access/xlog.h"
20#include "catalog/pg_control.h"
21#include "utils/guc.h"
22#include "utils/timestamp.h"
23
24/*
25 * GUC support
26 */
28 {"minimal", WAL_LEVEL_MINIMAL, false},
29 {"replica", WAL_LEVEL_REPLICA, false},
30 {"archive", WAL_LEVEL_REPLICA, true}, /* deprecated */
31 {"hot_standby", WAL_LEVEL_REPLICA, true}, /* deprecated */
32 {"logical", WAL_LEVEL_LOGICAL, false},
33 {NULL, 0, false}
34};
35
36/*
37 * Find a string representation for wal_level
38 */
39static const char *
41{
42 const struct config_enum_entry *entry;
43 const char *wal_level_str = "?";
44
45 for (entry = wal_level_options; entry->name; entry++)
46 {
47 if (entry->val == wal_level)
48 {
49 wal_level_str = entry->name;
50 break;
51 }
52 }
53
54 return wal_level_str;
55}
56
57void
59{
60 char *rec = XLogRecGetData(record);
61 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
62
63 if (info == XLOG_CHECKPOINT_SHUTDOWN ||
65 {
66 CheckPoint *checkpoint = (CheckPoint *) rec;
67
68 appendStringInfo(buf, "redo %X/%08X; "
69 "tli %u; prev tli %u; fpw %s; wal_level %s; logical decoding %s; xid %u:%u; oid %u; multi %u; offset %" PRIu64 "; "
70 "oldest xid %u in DB %u; oldest multi %u in DB %u; "
71 "oldest/newest commit timestamp xid: %u/%u; "
72 "oldest running xid %u; %s",
73 LSN_FORMAT_ARGS(checkpoint->redo),
74 checkpoint->ThisTimeLineID,
75 checkpoint->PrevTimeLineID,
76 checkpoint->fullPageWrites ? "true" : "false",
78 checkpoint->logicalDecodingEnabled ? "true" : "false",
81 checkpoint->nextOid,
82 checkpoint->nextMulti,
83 checkpoint->nextMultiOffset,
84 checkpoint->oldestXid,
85 checkpoint->oldestXidDB,
86 checkpoint->oldestMulti,
87 checkpoint->oldestMultiDB,
88 checkpoint->oldestCommitTsXid,
89 checkpoint->newestCommitTsXid,
90 checkpoint->oldestActiveXid,
91 (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
92 }
93 else if (info == XLOG_NEXTOID)
94 {
95 Oid nextOid;
96
97 memcpy(&nextOid, rec, sizeof(Oid));
98 appendStringInfo(buf, "%u", nextOid);
99 }
100 else if (info == XLOG_RESTORE_POINT)
101 {
102 xl_restore_point *xlrec = (xl_restore_point *) rec;
103
105 }
106 else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
107 {
108 /* no further information to print */
109 }
110 else if (info == XLOG_BACKUP_END)
111 {
112 XLogRecPtr startpoint;
113
114 memcpy(&startpoint, rec, sizeof(XLogRecPtr));
115 appendStringInfo(buf, "%X/%08X", LSN_FORMAT_ARGS(startpoint));
116 }
117 else if (info == XLOG_PARAMETER_CHANGE)
118 {
120 const char *wal_level_str;
121
122 memcpy(&xlrec, rec, sizeof(xl_parameter_change));
124
125 appendStringInfo(buf, "max_connections=%d max_worker_processes=%d "
126 "max_wal_senders=%d max_prepared_xacts=%d "
127 "max_locks_per_xact=%d wal_level=%s "
128 "wal_log_hints=%s track_commit_timestamp=%s",
129 xlrec.MaxConnections,
131 xlrec.max_wal_senders,
132 xlrec.max_prepared_xacts,
133 xlrec.max_locks_per_xact,
135 xlrec.wal_log_hints ? "on" : "off",
136 xlrec.track_commit_timestamp ? "on" : "off");
137 }
138 else if (info == XLOG_FPW_CHANGE)
139 {
140 bool fpw;
141
142 memcpy(&fpw, rec, sizeof(bool));
143 appendStringInfoString(buf, fpw ? "true" : "false");
144 }
145 else if (info == XLOG_END_OF_RECOVERY)
146 {
147 xl_end_of_recovery xlrec;
148
149 memcpy(&xlrec, rec, sizeof(xl_end_of_recovery));
150 appendStringInfo(buf, "tli %u; prev tli %u; time %s; wal_level %s",
151 xlrec.ThisTimeLineID, xlrec.PrevTimeLineID,
154 }
155 else if (info == XLOG_OVERWRITE_CONTRECORD)
156 {
158
159 memcpy(&xlrec, rec, sizeof(xl_overwrite_contrecord));
160 appendStringInfo(buf, "lsn %X/%08X; time %s",
163 }
164 else if (info == XLOG_CHECKPOINT_REDO)
165 {
166 int wal_level;
167
168 memcpy(&wal_level, rec, sizeof(int));
170 }
172 {
173 bool enabled;
174
175 memcpy(&enabled, rec, sizeof(bool));
176 appendStringInfoString(buf, enabled ? "true" : "false");
177 }
178}
179
180const char *
182{
183 const char *id = NULL;
184
185 switch (info & ~XLR_INFO_MASK)
186 {
188 id = "CHECKPOINT_SHUTDOWN";
189 break;
191 id = "CHECKPOINT_ONLINE";
192 break;
193 case XLOG_NOOP:
194 id = "NOOP";
195 break;
196 case XLOG_NEXTOID:
197 id = "NEXTOID";
198 break;
199 case XLOG_SWITCH:
200 id = "SWITCH";
201 break;
202 case XLOG_BACKUP_END:
203 id = "BACKUP_END";
204 break;
206 id = "PARAMETER_CHANGE";
207 break;
209 id = "RESTORE_POINT";
210 break;
211 case XLOG_FPW_CHANGE:
212 id = "FPW_CHANGE";
213 break;
215 id = "END_OF_RECOVERY";
216 break;
218 id = "OVERWRITE_CONTRECORD";
219 break;
220 case XLOG_FPI:
221 id = "FPI";
222 break;
224 id = "FPI_FOR_HINT";
225 break;
227 id = "CHECKPOINT_REDO";
228 break;
230 id = "LOGICAL_DECODING_STATUS_CHANGE";
231 break;
232 }
233
234 return id;
235}
236
237/*
238 * Returns a string giving information about all the blocks in an
239 * XLogRecord.
240 */
241void
243 bool detailed_format, StringInfo buf,
244 uint32 *fpi_len)
245{
246 int block_id;
247
248 Assert(record != NULL);
249
250 if (detailed_format && pretty)
252
253 for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
254 {
255 RelFileLocator rlocator;
256 ForkNumber forknum;
257 BlockNumber blk;
258
259 if (!XLogRecGetBlockTagExtended(record, block_id,
260 &rlocator, &forknum, &blk, NULL))
261 continue;
262
263 if (detailed_format)
264 {
265 /* Get block references in detailed format. */
266
267 if (pretty)
269 else if (block_id > 0)
271
273 "blkref #%d: rel %u/%u/%u fork %s blk %u",
274 block_id,
275 rlocator.spcOid, rlocator.dbOid, rlocator.relNumber,
276 forkNames[forknum],
277 blk);
278
279 if (XLogRecHasBlockImage(record, block_id))
280 {
281 uint8 bimg_info = XLogRecGetBlock(record, block_id)->bimg_info;
282
283 /* Calculate the amount of FPI data in the record. */
284 if (fpi_len)
285 *fpi_len += XLogRecGetBlock(record, block_id)->bimg_len;
286
287 if (BKPIMAGE_COMPRESSED(bimg_info))
288 {
289 const char *method;
290
291 if ((bimg_info & BKPIMAGE_COMPRESS_PGLZ) != 0)
292 method = "pglz";
293 else if ((bimg_info & BKPIMAGE_COMPRESS_LZ4) != 0)
294 method = "lz4";
295 else if ((bimg_info & BKPIMAGE_COMPRESS_ZSTD) != 0)
296 method = "zstd";
297 else
298 method = "unknown";
299
301 " (FPW%s); hole: offset: %u, length: %u, "
302 "compression saved: %u, method: %s",
303 XLogRecBlockImageApply(record, block_id) ?
304 "" : " for WAL verification",
305 XLogRecGetBlock(record, block_id)->hole_offset,
306 XLogRecGetBlock(record, block_id)->hole_length,
307 BLCKSZ -
308 XLogRecGetBlock(record, block_id)->hole_length -
309 XLogRecGetBlock(record, block_id)->bimg_len,
310 method);
311 }
312 else
313 {
315 " (FPW%s); hole: offset: %u, length: %u",
316 XLogRecBlockImageApply(record, block_id) ?
317 "" : " for WAL verification",
318 XLogRecGetBlock(record, block_id)->hole_offset,
319 XLogRecGetBlock(record, block_id)->hole_length);
320 }
321 }
322
323 if (pretty)
325 }
326 else
327 {
328 /* Get block references in short format. */
329
330 if (forknum != MAIN_FORKNUM)
331 {
333 ", blkref #%d: rel %u/%u/%u fork %s blk %u",
334 block_id,
335 rlocator.spcOid, rlocator.dbOid, rlocator.relNumber,
336 forkNames[forknum],
337 blk);
338 }
339 else
340 {
342 ", blkref #%d: rel %u/%u/%u blk %u",
343 block_id,
344 rlocator.spcOid, rlocator.dbOid, rlocator.relNumber,
345 blk);
346 }
347
348 if (XLogRecHasBlockImage(record, block_id))
349 {
350 /* Calculate the amount of FPI data in the record. */
351 if (fpi_len)
352 *fpi_len += XLogRecGetBlock(record, block_id)->bimg_len;
353
354 if (XLogRecBlockImageApply(record, block_id))
356 else
357 appendStringInfoString(buf, " FPW for WAL verification");
358 }
359 }
360 }
361
362 if (!detailed_format && pretty)
364}
const char * timestamptz_to_str(TimestampTz t)
Definition: timestamp.c:1862
static const char * wal_level_str(WalLevel wal_level)
uint32 BlockNumber
Definition: block.h:31
uint8_t uint8
Definition: c.h:550
uint32_t uint32
Definition: c.h:552
Assert(PointerIsAligned(start, uint64))
#define XLOG_RESTORE_POINT
Definition: pg_control.h:76
#define XLOG_FPW_CHANGE
Definition: pg_control.h:77
#define XLOG_CHECKPOINT_REDO
Definition: pg_control.h:83
#define XLOG_OVERWRITE_CONTRECORD
Definition: pg_control.h:82
#define XLOG_FPI
Definition: pg_control.h:80
#define XLOG_FPI_FOR_HINT
Definition: pg_control.h:79
#define XLOG_NEXTOID
Definition: pg_control.h:72
#define XLOG_NOOP
Definition: pg_control.h:71
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:69
#define XLOG_SWITCH
Definition: pg_control.h:73
#define XLOG_BACKUP_END
Definition: pg_control.h:74
#define XLOG_PARAMETER_CHANGE
Definition: pg_control.h:75
#define XLOG_LOGICAL_DECODING_STATUS_CHANGE
Definition: pg_control.h:84
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:70
#define XLOG_END_OF_RECOVERY
Definition: pg_control.h:78
static char buf[DEFAULT_XLOG_SEG_SIZE]
Definition: pg_test_fsync.c:71
unsigned int Oid
Definition: postgres_ext.h:32
const char *const forkNames[]
Definition: relpath.c:33
ForkNumber
Definition: relpath.h:56
@ MAIN_FORKNUM
Definition: relpath.h:58
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
Oid oldestMultiDB
Definition: pg_control.h:52
MultiXactId oldestMulti
Definition: pg_control.h:51
MultiXactOffset nextMultiOffset
Definition: pg_control.h:48
TransactionId newestCommitTsXid
Definition: pg_control.h:56
TransactionId oldestXid
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:46
TransactionId oldestActiveXid
Definition: pg_control.h:65
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:47
FullTransactionId nextXid
Definition: pg_control.h:45
TransactionId oldestCommitTsXid
Definition: pg_control.h:54
int wal_level
Definition: pg_control.h:43
bool logicalDecodingEnabled
Definition: pg_control.h:44
XLogRecPtr redo
Definition: pg_control.h:37
Oid oldestXidDB
Definition: pg_control.h:50
RelFileNumber relNumber
Definition: guc.h:174
const char * name
Definition: guc.h:175
int val
Definition: guc.h:176
TimeLineID PrevTimeLineID
TimestampTz end_time
TimeLineID ThisTimeLineID
char rp_name[MAXFNAMELEN]
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
#define XidFromFullTransactionId(x)
Definition: transam.h:48
int wal_level
Definition: xlog.c:134
@ WAL_LEVEL_REPLICA
Definition: xlog.h:76
@ WAL_LEVEL_LOGICAL
Definition: xlog.h:77
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:75
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:47
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static const char * get_wal_level_string(int wal_level)
Definition: xlogdesc.c:40
void xlog_desc(StringInfo buf, XLogReaderState *record)
Definition: xlogdesc.c:58
void XLogRecGetBlockRefInfo(XLogReaderState *record, bool pretty, bool detailed_format, StringInfo buf, uint32 *fpi_len)
Definition: xlogdesc.c:242
const char * xlog_identify(uint8 info)
Definition: xlogdesc.c:181
const struct config_enum_entry wal_level_options[]
Definition: xlogdesc.c:27
bool XLogRecGetBlockTagExtended(XLogReaderState *record, uint8 block_id, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum, Buffer *prefetch_buffer)
Definition: xlogreader.c:2017
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:409
#define XLogRecBlockImageApply(decoder, block_id)
Definition: xlogreader.h:424
#define XLogRecGetData(decoder)
Definition: xlogreader.h:414
#define XLogRecGetBlock(decoder, i)
Definition: xlogreader.h:418
#define XLogRecMaxBlockId(decoder)
Definition: xlogreader.h:417
#define XLogRecHasBlockImage(decoder, block_id)
Definition: xlogreader.h:422
#define BKPIMAGE_COMPRESS_ZSTD
Definition: xlogrecord.h:162
#define BKPIMAGE_COMPRESS_LZ4
Definition: xlogrecord.h:161
#define BKPIMAGE_COMPRESSED(info)
Definition: xlogrecord.h:164
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define BKPIMAGE_COMPRESS_PGLZ
Definition: xlogrecord.h:160