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-2018, 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 0xD098	/* can be used as WAL version indicator */
35 
36 typedef struct XLogPageHeaderData
37 {
38 	uint16		xlp_magic;		/* magic value for correctness checks */
39 	uint16		xlp_info;		/* flag bits, see below */
40 	TimeLineID	xlp_tli;		/* TimeLineID of first record on page */
41 	XLogRecPtr	xlp_pageaddr;	/* 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		xlp_rem_len;	/* total len of remaining data for record */
53 } XLogPageHeaderData;
54 
55 #define SizeOfXLogShortPHD	MAXALIGN(sizeof(XLogPageHeaderData))
56 
57 typedef XLogPageHeaderData *XLogPageHeader;
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 XLogLongPageHeaderData
65 {
66 	XLogPageHeaderData std;		/* standard header fields */
67 	uint64		xlp_sysid;		/* system identifier from pg_control */
68 	uint32		xlp_seg_size;	/* just as a cross-check */
69 	uint32		xlp_xlog_blcksz;	/* just as a cross-check */
70 } XLogLongPageHeaderData;
71 
72 #define SizeOfXLogLongPHD	MAXALIGN(sizeof(XLogLongPageHeaderData))
73 
74 typedef XLogLongPageHeaderData *XLogLongPageHeader;
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 XLP_LONG_HEADER				0x0002
80 /* This flag indicates backup blocks starting in this page are optional */
81 #define XLP_BKP_REMOVABLE			0x0004
82 /* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */
83 #define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008
84 /* All defined flag bits in xlp_info (used for validity checking of header) */
85 #define XLP_ALL_FLAGS				0x000F
86 
87 #define XLogPageHeaderSize(hdr)		\
88 	(((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)
89 
90 /* wal_segment_size can range from 1MB to 1GB */
91 #define WalSegMinSize 1024 * 1024
92 #define WalSegMaxSize 1024 * 1024 * 1024
93 /* default number of min and max wal segments */
94 #define DEFAULT_MIN_WAL_SEGS 5
95 #define DEFAULT_MAX_WAL_SEGS 64
96 
97 /* check that the given size is a valid wal_segment_size */
98 #define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0)
99 #define IsValidWalSegSize(size) \
100 	 (IsPowerOf2(size) && \
101 	 ((size) >= WalSegMinSize && (size) <= WalSegMaxSize))
102 
103 #define XLogSegmentsPerXLogId(wal_segsz_bytes)	\
104 	(UINT64CONST(0x100000000) / (wal_segsz_bytes))
105 
106 #define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \
107 		(dest) = (segno) * (wal_segsz_bytes) + (offset)
108 
109 #define XLogSegmentOffset(xlogptr, wal_segsz_bytes)	\
110 	((xlogptr) & ((wal_segsz_bytes) - 1))
111 
112 /*
113  * Compute a segment number from an XLogRecPtr.
114  *
115  * For XLByteToSeg, do the computation at face value.  For XLByteToPrevSeg,
116  * a boundary byte is taken to be in the previous segment.  This is suitable
117  * for deciding which segment to write given a pointer to a record end,
118  * for example.
119  */
120 #define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \
121 	logSegNo = (xlrp) / (wal_segsz_bytes)
122 
123 #define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
124 	logSegNo = ((xlrp) - 1) / (wal_segsz_bytes)
125 
126 /*
127  * Is an XLogRecPtr within a particular XLOG segment?
128  *
129  * For XLByteInSeg, do the computation at face value.  For XLByteInPrevSeg,
130  * a boundary byte is taken to be in the previous segment.
131  */
132 #define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \
133 	(((xlrp) / (wal_segsz_bytes)) == (logSegNo))
134 
135 #define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
136 	((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo))
137 
138 /* Check if an XLogRecPtr value is in a plausible range */
139 #define XRecOffIsValid(xlrp) \
140 		((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD)
141 
142 /*
143  * The XLog directory and control file (relative to $PGDATA)
144  */
145 #define XLOGDIR				"pg_wal"
146 #define XLOG_CONTROL_FILE	"global/pg_control"
147 
148 /*
149  * These macros encapsulate knowledge about the exact layout of XLog file
150  * names, timeline history file names, and archive-status file names.
151  */
152 #define MAXFNAMELEN		64
153 
154 /* Length of XLog file name */
155 #define XLOG_FNAME_LEN	   24
156 
157 #define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)	\
158 	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli,		\
159 			 (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \
160 			 (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)))
161 
162 #define XLogFileNameById(fname, tli, log, seg)	\
163 	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg)
164 
165 #define IsXLogFileName(fname) \
166 	(strlen(fname) == XLOG_FNAME_LEN && \
167 	 strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN)
168 
169 /*
170  * XLOG segment with .partial suffix.  Used by pg_receivewal and at end of
171  * archive recovery, when we want to archive a WAL segment but it might not
172  * be complete yet.
173  */
174 #define IsPartialXLogFileName(fname)	\
175 	(strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") &&	\
176 	 strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&		\
177 	 strcmp((fname) + XLOG_FNAME_LEN, ".partial") == 0)
178 
179 #define XLogFromFileName(fname, tli, logSegNo, wal_segsz_bytes)	\
180 	do {												\
181 		uint32 log;										\
182 		uint32 seg;										\
183 		sscanf(fname, "%08X%08X%08X", tli, &log, &seg); \
184 		*logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg; \
185 	} while (0)
186 
187 #define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes)	\
188 	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli,	\
189 			 (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \
190 			 (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)))
191 
192 #define TLHistoryFileName(fname, tli)	\
193 	snprintf(fname, MAXFNAMELEN, "%08X.history", tli)
194 
195 #define IsTLHistoryFileName(fname)	\
196 	(strlen(fname) == 8 + strlen(".history") &&		\
197 	 strspn(fname, "0123456789ABCDEF") == 8 &&		\
198 	 strcmp((fname) + 8, ".history") == 0)
199 
200 #define TLHistoryFilePath(path, tli)	\
201 	snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli)
202 
203 #define StatusFilePath(path, xlog, suffix)	\
204 	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix)
205 
206 #define BackupHistoryFileName(fname, tli, logSegNo, startpoint, wal_segsz_bytes) \
207 	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, \
208 			 (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \
209 			 (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)), \
210 			 (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes)))
211 
212 #define IsBackupHistoryFileName(fname) \
213 	(strlen(fname) > XLOG_FNAME_LEN && \
214 	 strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && \
215 	 strcmp((fname) + strlen(fname) - strlen(".backup"), ".backup") == 0)
216 
217 #define BackupHistoryFilePath(path, tli, logSegNo, startpoint, wal_segsz_bytes)	\
218 	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, \
219 			 (uint32) ((logSegNo) / XLogSegmentsPerXLogId(wal_segsz_bytes)), \
220 			 (uint32) ((logSegNo) % XLogSegmentsPerXLogId(wal_segsz_bytes)), \
221 			 (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes)))
222 
223 /*
224  * Information logged when we detect a change in one of the parameters
225  * important for Hot Standby.
226  */
227 typedef struct xl_parameter_change
228 {
229 	int			MaxConnections;
230 	int			max_worker_processes;
231 	int			max_prepared_xacts;
232 	int			max_locks_per_xact;
233 	int			wal_level;
234 	bool		wal_log_hints;
235 	bool		track_commit_timestamp;
236 } xl_parameter_change;
237 
238 /* logs restore point */
239 typedef struct xl_restore_point
240 {
241 	TimestampTz rp_time;
242 	char		rp_name[MAXFNAMELEN];
243 } xl_restore_point;
244 
245 /* Overwrite of prior contrecord */
246 typedef struct xl_overwrite_contrecord
247 {
248 	XLogRecPtr	overwritten_lsn;
249 	TimestampTz overwrite_time;
250 } xl_overwrite_contrecord;
251 
252 /* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */
253 typedef struct xl_end_of_recovery
254 {
255 	TimestampTz end_time;
256 	TimeLineID	ThisTimeLineID; /* new TLI */
257 	TimeLineID	PrevTimeLineID; /* previous TLI we forked off from */
258 } xl_end_of_recovery;
259 
260 /*
261  * The functions in xloginsert.c construct a chain of XLogRecData structs
262  * to represent the final WAL record.
263  */
264 typedef struct XLogRecData
265 {
266 	struct XLogRecData *next;	/* next struct in chain, or NULL */
267 	char	   *data;			/* start of rmgr data to include */
268 	uint32		len;			/* length of rmgr data to include */
269 } XLogRecData;
270 
271 /*
272  * Recovery target action.
273  */
274 typedef enum
275 {
276 	RECOVERY_TARGET_ACTION_PAUSE,
277 	RECOVERY_TARGET_ACTION_PROMOTE,
278 	RECOVERY_TARGET_ACTION_SHUTDOWN
279 } RecoveryTargetAction;
280 
281 /*
282  * Method table for resource managers.
283  *
284  * This struct must be kept in sync with the PG_RMGR definition in
285  * rmgr.c.
286  *
287  * rm_identify must return a name for the record based on xl_info (without
288  * reference to the rmid). For example, XLOG_BTREE_VACUUM would be named
289  * "VACUUM". rm_desc can then be called to obtain additional detail for the
290  * record, if available (e.g. the last block).
291  *
292  * rm_mask takes as input a page modified by the resource manager and masks
293  * out bits that shouldn't be flagged by wal_consistency_checking.
294  *
295  * RmgrTable[] is indexed by RmgrId values (see rmgrlist.h).
296  */
297 typedef struct RmgrData
298 {
299 	const char *rm_name;
300 	void		(*rm_redo) (XLogReaderState *record);
301 	void		(*rm_desc) (StringInfo buf, XLogReaderState *record);
302 	const char *(*rm_identify) (uint8 info);
303 	void		(*rm_startup) (void);
304 	void		(*rm_cleanup) (void);
305 	void		(*rm_mask) (char *pagedata, BlockNumber blkno);
306 } RmgrData;
307 
308 extern const RmgrData RmgrTable[];
309 
310 /*
311  * Exported to support xlog switching from checkpointer
312  */
313 extern pg_time_t GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN);
314 extern XLogRecPtr RequestXLogSwitch(bool mark_unimportant);
315 
316 extern void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli);
317 
318 /*
319  * Exported for the functions in timeline.c and xlogarchive.c.  Only valid
320  * in the startup process.
321  */
322 extern bool ArchiveRecoveryRequested;
323 extern bool InArchiveRecovery;
324 extern bool StandbyMode;
325 extern char *recoveryRestoreCommand;
326 
327 /*
328  * Prototypes for functions in xlogarchive.c
329  */
330 extern bool RestoreArchivedFile(char *path, const char *xlogfname,
331 					const char *recovername, off_t expectedSize,
332 					bool cleanupEnabled);
333 extern void ExecuteRecoveryCommand(const char *command, const char *commandName,
334 					   bool failOnerror);
335 extern void KeepFileRestoredFromArchive(const char *path, const char *xlogfname);
336 extern void XLogArchiveNotify(const char *xlog);
337 extern void XLogArchiveNotifySeg(XLogSegNo segno);
338 extern void XLogArchiveForceDone(const char *xlog);
339 extern bool XLogArchiveCheckDone(const char *xlog);
340 extern bool XLogArchiveIsBusy(const char *xlog);
341 extern bool XLogArchiveIsReady(const char *xlog);
342 extern bool XLogArchiveIsReadyOrDone(const char *xlog);
343 extern void XLogArchiveCleanup(const char *xlog);
344 
345 #endif							/* XLOG_INTERNAL_H */
346