1 | /* |
2 | * xlog_internal.h |
3 | * |
4 | * PostgreSQL write-ahead log internal declarations |
5 | * |
6 | * NOTE: this file is intended to contain declarations useful for |
7 | * manipulating the XLOG files directly, but it is not supposed to be |
8 | * needed by rmgr routines (redo support for individual record types). |
9 | * So the XLogRecord typedef and associated stuff appear in xlogrecord.h. |
10 | * |
11 | * Note: This file must be includable in both frontend and backend contexts, |
12 | * to allow stand-alone tools like pg_receivewal to deal with WAL files. |
13 | * |
14 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
15 | * Portions Copyright (c) 1994, Regents of the University of California |
16 | * |
17 | * src/include/access/xlog_internal.h |
18 | */ |
19 | #ifndef XLOG_INTERNAL_H |
20 | #define XLOG_INTERNAL_H |
21 | |
22 | #include "access/xlogdefs.h" |
23 | #include "access/xlogreader.h" |
24 | #include "datatype/timestamp.h" |
25 | #include "lib/stringinfo.h" |
26 | #include "pgtime.h" |
27 | #include "storage/block.h" |
28 | #include "storage/relfilenode.h" |
29 | |
30 | |
31 | /* |
32 | * Each page of XLOG file has a header like this: |
33 | */ |
34 | #define XLOG_PAGE_MAGIC 0xD101 /* can be used as WAL version indicator */ |
35 | |
36 | typedef struct |
37 | { |
38 | uint16 ; /* magic value for correctness checks */ |
39 | uint16 ; /* flag bits, see below */ |
40 | TimeLineID ; /* TimeLineID of first record on page */ |
41 | XLogRecPtr ; /* XLOG address of this page */ |
42 | |
43 | /* |
44 | * When there is not enough space on current page for whole record, we |
45 | * continue on the next page. xlp_rem_len is the number of bytes |
46 | * remaining from a previous page. |
47 | * |
48 | * Note that xl_rem_len includes backup-block data; that is, it tracks |
49 | * xl_tot_len not xl_len in the initial header. Also note that the |
50 | * continuation data isn't necessarily aligned. |
51 | */ |
52 | uint32 ; /* total len of remaining data for record */ |
53 | } ; |
54 | |
55 | #define SizeOfXLogShortPHD MAXALIGN(sizeof(XLogPageHeaderData)) |
56 | |
57 | typedef XLogPageHeaderData *; |
58 | |
59 | /* |
60 | * When the XLP_LONG_HEADER flag is set, we store additional fields in the |
61 | * page header. (This is ordinarily done just in the first page of an |
62 | * XLOG file.) The additional fields serve to identify the file accurately. |
63 | */ |
64 | typedef struct |
65 | { |
66 | XLogPageHeaderData ; /* standard header fields */ |
67 | uint64 ; /* system identifier from pg_control */ |
68 | uint32 ; /* just as a cross-check */ |
69 | uint32 ; /* just as a cross-check */ |
70 | } ; |
71 | |
72 | #define SizeOfXLogLongPHD MAXALIGN(sizeof(XLogLongPageHeaderData)) |
73 | |
74 | typedef XLogLongPageHeaderData *; |
75 | |
76 | /* When record crosses page boundary, set this flag in new page's header */ |
77 | #define XLP_FIRST_IS_CONTRECORD 0x0001 |
78 | /* This flag indicates a "long" page header */ |
79 | #define 0x0002 |
80 | /* This flag indicates backup blocks starting in this page are optional */ |
81 | #define XLP_BKP_REMOVABLE 0x0004 |
82 | /* All defined flag bits in xlp_info (used for validity checking of header) */ |
83 | #define XLP_ALL_FLAGS 0x0007 |
84 | |
85 | #define (hdr) \ |
86 | (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) |
87 | |
88 | /* wal_segment_size can range from 1MB to 1GB */ |
89 | #define WalSegMinSize 1024 * 1024 |
90 | #define WalSegMaxSize 1024 * 1024 * 1024 |
91 | /* default number of min and max wal segments */ |
92 | #define DEFAULT_MIN_WAL_SEGS 5 |
93 | #define DEFAULT_MAX_WAL_SEGS 64 |
94 | |
95 | /* check that the given size is a valid wal_segment_size */ |
96 | #define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0) |
97 | #define IsValidWalSegSize(size) \ |
98 | (IsPowerOf2(size) && \ |
99 | ((size) >= WalSegMinSize && (size) <= WalSegMaxSize)) |
100 | |
101 | #define XLogSegmentsPerXLogId(wal_segsz_bytes) \ |
102 | (UINT64CONST(0x100000000) / (wal_segsz_bytes)) |
103 | |
104 | #define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \ |
105 | (dest) = (segno) * (wal_segsz_bytes) + (offset) |
106 | |
107 | #define XLogSegmentOffset(xlogptr, wal_segsz_bytes) \ |
108 | ((xlogptr) & ((wal_segsz_bytes) - 1)) |
109 | |
110 | /* |
111 | * Compute a segment number from an XLogRecPtr. |
112 | * |
113 | * For XLByteToSeg, do the computation at face value. For XLByteToPrevSeg, |
114 | * a boundary byte is taken to be in the previous segment. This is suitable |
115 | * for deciding which segment to write given a pointer to a record end, |
116 | * for example. |
117 | */ |
118 | #define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \ |
119 | logSegNo = (xlrp) / (wal_segsz_bytes) |
120 | |
121 | #define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \ |
122 | logSegNo = ((xlrp) - 1) / (wal_segsz_bytes) |
123 | |
124 | /* |
125 | * Is an XLogRecPtr within a particular XLOG segment? |
126 | * |
127 | * For XLByteInSeg, do the computation at face value. For XLByteInPrevSeg, |
128 | * a boundary byte is taken to be in the previous segment. |
129 | */ |
130 | #define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \ |
131 | (((xlrp) / (wal_segsz_bytes)) == (logSegNo)) |
132 | |
133 | #define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \ |
134 | ((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo)) |
135 | |
136 | /* Check if an XLogRecPtr value is in a plausible range */ |
137 | #define XRecOffIsValid(xlrp) \ |
138 | ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD) |
139 | |
140 | /* |
141 | * The XLog directory and control file (relative to $PGDATA) |
142 | */ |
143 | #define XLOGDIR "pg_wal" |
144 | #define XLOG_CONTROL_FILE "global/pg_control" |
145 | |
146 | /* |
147 | * These macros encapsulate knowledge about the exact layout of XLog file |
148 | * names, timeline history file names, and archive-status file names. |
149 | */ |
150 | #define MAXFNAMELEN 64 |
151 | |
152 | /* Length of XLog file name */ |
153 | #define XLOG_FNAME_LEN 24 |
154 | |
155 | #define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes) \ |
156 | snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, \ |
157 | (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
158 | (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes))) |
159 | |
160 | #define XLogFileNameById(fname, tli, log, seg) \ |
161 | snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg) |
162 | |
163 | #define IsXLogFileName(fname) \ |
164 | (strlen(fname) == XLOG_FNAME_LEN && \ |
165 | strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN) |
166 | |
167 | /* |
168 | * XLOG segment with .partial suffix. Used by pg_receivewal and at end of |
169 | * archive recovery, when we want to archive a WAL segment but it might not |
170 | * be complete yet. |
171 | */ |
172 | #define IsPartialXLogFileName(fname) \ |
173 | (strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") && \ |
174 | strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && \ |
175 | strcmp((fname) + XLOG_FNAME_LEN, ".partial") == 0) |
176 | |
177 | #define XLogFromFileName(fname, tli, logSegNo, wal_segsz_bytes) \ |
178 | do { \ |
179 | uint32 log; \ |
180 | uint32 seg; \ |
181 | sscanf(fname, "%08X%08X%08X", tli, &log, &seg); \ |
182 | *logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg; \ |
183 | } while (0) |
184 | |
185 | #define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes) \ |
186 | snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, \ |
187 | (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
188 | (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes))) |
189 | |
190 | #define TLHistoryFileName(fname, tli) \ |
191 | snprintf(fname, MAXFNAMELEN, "%08X.history", tli) |
192 | |
193 | #define IsTLHistoryFileName(fname) \ |
194 | (strlen(fname) == 8 + strlen(".history") && \ |
195 | strspn(fname, "0123456789ABCDEF") == 8 && \ |
196 | strcmp((fname) + 8, ".history") == 0) |
197 | |
198 | #define TLHistoryFilePath(path, tli) \ |
199 | snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli) |
200 | |
201 | #define StatusFilePath(path, xlog, suffix) \ |
202 | snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix) |
203 | |
204 | #define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes) \ |
205 | snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, \ |
206 | (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
207 | (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
208 | (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes))) |
209 | |
210 | #define IsBackupHistoryFileName(fname) \ |
211 | (strlen(fname) > XLOG_FNAME_LEN && \ |
212 | strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && \ |
213 | strcmp((fname) + strlen(fname) - strlen(".backup"), ".backup") == 0) |
214 | |
215 | #define BackupHistoryFilePath(path, tli, logSegNo, startpoint, wal_segsz_bytes) \ |
216 | snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, \ |
217 | (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
218 | (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)), \ |
219 | (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes))) |
220 | |
221 | /* |
222 | * Information logged when we detect a change in one of the parameters |
223 | * important for Hot Standby. |
224 | */ |
225 | typedef struct xl_parameter_change |
226 | { |
227 | int MaxConnections; |
228 | int max_worker_processes; |
229 | int max_wal_senders; |
230 | int max_prepared_xacts; |
231 | int max_locks_per_xact; |
232 | int wal_level; |
233 | bool wal_log_hints; |
234 | bool track_commit_timestamp; |
235 | } xl_parameter_change; |
236 | |
237 | /* logs restore point */ |
238 | typedef struct xl_restore_point |
239 | { |
240 | TimestampTz rp_time; |
241 | char rp_name[MAXFNAMELEN]; |
242 | } xl_restore_point; |
243 | |
244 | /* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */ |
245 | typedef struct xl_end_of_recovery |
246 | { |
247 | TimestampTz end_time; |
248 | TimeLineID ThisTimeLineID; /* new TLI */ |
249 | TimeLineID PrevTimeLineID; /* previous TLI we forked off from */ |
250 | } xl_end_of_recovery; |
251 | |
252 | /* |
253 | * The functions in xloginsert.c construct a chain of XLogRecData structs |
254 | * to represent the final WAL record. |
255 | */ |
256 | typedef struct XLogRecData |
257 | { |
258 | struct XLogRecData *next; /* next struct in chain, or NULL */ |
259 | char *data; /* start of rmgr data to include */ |
260 | uint32 len; /* length of rmgr data to include */ |
261 | } XLogRecData; |
262 | |
263 | /* |
264 | * Recovery target action. |
265 | */ |
266 | typedef enum |
267 | { |
268 | RECOVERY_TARGET_ACTION_PAUSE, |
269 | RECOVERY_TARGET_ACTION_PROMOTE, |
270 | RECOVERY_TARGET_ACTION_SHUTDOWN |
271 | } RecoveryTargetAction; |
272 | |
273 | /* |
274 | * Method table for resource managers. |
275 | * |
276 | * This struct must be kept in sync with the PG_RMGR definition in |
277 | * rmgr.c. |
278 | * |
279 | * rm_identify must return a name for the record based on xl_info (without |
280 | * reference to the rmid). For example, XLOG_BTREE_VACUUM would be named |
281 | * "VACUUM". rm_desc can then be called to obtain additional detail for the |
282 | * record, if available (e.g. the last block). |
283 | * |
284 | * rm_mask takes as input a page modified by the resource manager and masks |
285 | * out bits that shouldn't be flagged by wal_consistency_checking. |
286 | * |
287 | * RmgrTable[] is indexed by RmgrId values (see rmgrlist.h). |
288 | */ |
289 | typedef struct RmgrData |
290 | { |
291 | const char *rm_name; |
292 | void (*rm_redo) (XLogReaderState *record); |
293 | void (*rm_desc) (StringInfo buf, XLogReaderState *record); |
294 | const char *(*rm_identify) (uint8 info); |
295 | void (*rm_startup) (void); |
296 | void (*rm_cleanup) (void); |
297 | void (*rm_mask) (char *pagedata, BlockNumber blkno); |
298 | } RmgrData; |
299 | |
300 | extern const RmgrData RmgrTable[]; |
301 | |
302 | /* |
303 | * Exported to support xlog switching from checkpointer |
304 | */ |
305 | extern pg_time_t GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN); |
306 | extern XLogRecPtr RequestXLogSwitch(bool mark_unimportant); |
307 | |
308 | extern void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli); |
309 | |
310 | /* |
311 | * Exported for the functions in timeline.c and xlogarchive.c. Only valid |
312 | * in the startup process. |
313 | */ |
314 | extern bool ArchiveRecoveryRequested; |
315 | extern bool InArchiveRecovery; |
316 | extern bool StandbyMode; |
317 | extern char *recoveryRestoreCommand; |
318 | |
319 | /* |
320 | * Prototypes for functions in xlogarchive.c |
321 | */ |
322 | extern bool RestoreArchivedFile(char *path, const char *xlogfname, |
323 | const char *recovername, off_t expectedSize, |
324 | bool cleanupEnabled); |
325 | extern void ExecuteRecoveryCommand(const char *command, const char *commandName, |
326 | bool failOnerror); |
327 | extern void KeepFileRestoredFromArchive(const char *path, const char *xlogfname); |
328 | extern void XLogArchiveNotify(const char *xlog); |
329 | extern void XLogArchiveNotifySeg(XLogSegNo segno); |
330 | extern void XLogArchiveForceDone(const char *xlog); |
331 | extern bool XLogArchiveCheckDone(const char *xlog); |
332 | extern bool XLogArchiveIsBusy(const char *xlog); |
333 | extern bool XLogArchiveIsReady(const char *xlog); |
334 | extern bool XLogArchiveIsReadyOrDone(const char *xlog); |
335 | extern void XLogArchiveCleanup(const char *xlog); |
336 | |
337 | #endif /* XLOG_INTERNAL_H */ |
338 | |