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