1 /*-------------------------------------------------------------------------
2  *
3  * xlogreader.h
4  *		Definitions for the generic XLog reading facility
5  *
6  * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *		src/include/access/xlogreader.h
10  *
11  * NOTES
12  *		See the definition of the XLogReaderState struct for instructions on
13  *		how to use the XLogReader infrastructure.
14  *
15  *		The basic idea is to allocate an XLogReaderState via
16  *		XLogReaderAllocate(), and call XLogReadRecord() until it returns NULL.
17  *
18  *		After reading a record with XLogReadRecord(), it's decomposed into
19  *		the per-block and main data parts, and the parts can be accessed
20  *		with the XLogRec* macros and functions. You can also decode a
21  *		record that's already constructed in memory, without reading from
22  *		disk, by calling the DecodeXLogRecord() function.
23  *-------------------------------------------------------------------------
24  */
25 #ifndef XLOGREADER_H
26 #define XLOGREADER_H
27 
28 #include "access/xlogrecord.h"
29 
30 typedef struct XLogReaderState XLogReaderState;
31 
32 /* Function type definition for the read_page callback */
33 typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader,
34 							   XLogRecPtr targetPagePtr,
35 							   int reqLen,
36 							   XLogRecPtr targetRecPtr,
37 							   char *readBuf,
38 							   TimeLineID *pageTLI);
39 
40 typedef struct
41 {
42 	/* Is this block ref in use? */
43 	bool		in_use;
44 
45 	/* Identify the block this refers to */
46 	RelFileNode rnode;
47 	ForkNumber	forknum;
48 	BlockNumber blkno;
49 
50 	/* copy of the fork_flags field from the XLogRecordBlockHeader */
51 	uint8		flags;
52 
53 	/* Information on full-page image, if any */
54 	bool		has_image;		/* has image, even for consistency checking */
55 	bool		apply_image;	/* has image that should be restored */
56 	char	   *bkp_image;
57 	uint16		hole_offset;
58 	uint16		hole_length;
59 	uint16		bimg_len;
60 	uint8		bimg_info;
61 
62 	/* Buffer holding the rmgr-specific data associated with this block */
63 	bool		has_data;
64 	char	   *data;
65 	uint16		data_len;
66 	uint16		data_bufsz;
67 } DecodedBkpBlock;
68 
69 struct XLogReaderState
70 {
71 	/* ----------------------------------------
72 	 * Public parameters
73 	 * ----------------------------------------
74 	 */
75 
76 	/*
77 	 * Segment size of the to-be-parsed data (mandatory).
78 	 */
79 	int			wal_segment_size;
80 
81 	/*
82 	 * Data input callback (mandatory).
83 	 *
84 	 * This callback shall read at least reqLen valid bytes of the xlog page
85 	 * starting at targetPagePtr, and store them in readBuf.  The callback
86 	 * shall return the number of bytes read (never more than XLOG_BLCKSZ), or
87 	 * -1 on failure.  The callback shall sleep, if necessary, to wait for the
88 	 * requested bytes to become available.  The callback will not be invoked
89 	 * again for the same page unless more than the returned number of bytes
90 	 * are needed.
91 	 *
92 	 * targetRecPtr is the position of the WAL record we're reading.  Usually
93 	 * it is equal to targetPagePtr + reqLen, but sometimes xlogreader needs
94 	 * to read and verify the page or segment header, before it reads the
95 	 * actual WAL record it's interested in.  In that case, targetRecPtr can
96 	 * be used to determine which timeline to read the page from.
97 	 *
98 	 * The callback shall set *pageTLI to the TLI of the file the page was
99 	 * read from.  It is currently used only for error reporting purposes, to
100 	 * reconstruct the name of the WAL file where an error occurred.
101 	 */
102 	XLogPageReadCB read_page;
103 
104 	/*
105 	 * System identifier of the xlog files we're about to read.  Set to zero
106 	 * (the default value) if unknown or unimportant.
107 	 */
108 	uint64		system_identifier;
109 
110 	/*
111 	 * Opaque data for callbacks to use.  Not used by XLogReader.
112 	 */
113 	void	   *private_data;
114 
115 	/*
116 	 * Start and end point of last record read.  EndRecPtr is also used as the
117 	 * position to read next, if XLogReadRecord receives an invalid recptr.
118 	 */
119 	XLogRecPtr	ReadRecPtr;		/* start of last record read */
120 	XLogRecPtr	EndRecPtr;		/* end+1 of last record read */
121 
122 
123 	/* ----------------------------------------
124 	 * Decoded representation of current record
125 	 *
126 	 * Use XLogRecGet* functions to investigate the record; these fields
127 	 * should not be accessed directly.
128 	 * ----------------------------------------
129 	 */
130 	XLogRecord *decoded_record; /* currently decoded record */
131 
132 	char	   *main_data;		/* record's main data portion */
133 	uint32		main_data_len;	/* main data portion's length */
134 	uint32		main_data_bufsz;	/* allocated size of the buffer */
135 
136 	RepOriginId record_origin;
137 
138 	/* information about blocks referenced by the record. */
139 	DecodedBkpBlock blocks[XLR_MAX_BLOCK_ID + 1];
140 
141 	int			max_block_id;	/* highest block_id in use (-1 if none) */
142 
143 	/* ----------------------------------------
144 	 * private/internal state
145 	 * ----------------------------------------
146 	 */
147 
148 	/*
149 	 * Buffer for currently read page (XLOG_BLCKSZ bytes, valid up to at least
150 	 * readLen bytes)
151 	 */
152 	char	   *readBuf;
153 	uint32		readLen;
154 
155 	/* last read segment, segment offset, TLI for data currently in readBuf */
156 	XLogSegNo	readSegNo;
157 	uint32		readOff;
158 	TimeLineID	readPageTLI;
159 
160 	/*
161 	 * beginning of prior page read, and its TLI.  Doesn't necessarily
162 	 * correspond to what's in readBuf; used for timeline sanity checks.
163 	 */
164 	XLogRecPtr	latestPagePtr;
165 	TimeLineID	latestPageTLI;
166 
167 	/* beginning of the WAL record being read. */
168 	XLogRecPtr	currRecPtr;
169 	/* timeline to read it from, 0 if a lookup is required */
170 	TimeLineID	currTLI;
171 
172 	/*
173 	 * Safe point to read to in currTLI if current TLI is historical
174 	 * (tliSwitchPoint) or InvalidXLogRecPtr if on current timeline.
175 	 *
176 	 * Actually set to the start of the segment containing the timeline switch
177 	 * that ends currTLI's validity, not the LSN of the switch its self, since
178 	 * we can't assume the old segment will be present.
179 	 */
180 	XLogRecPtr	currTLIValidUntil;
181 
182 	/*
183 	 * If currTLI is not the most recent known timeline, the next timeline to
184 	 * read from when currTLIValidUntil is reached.
185 	 */
186 	TimeLineID	nextTLI;
187 
188 	/*
189 	 * Buffer for current ReadRecord result (expandable), used when a record
190 	 * crosses a page boundary.
191 	 */
192 	char	   *readRecordBuf;
193 	uint32		readRecordBufSize;
194 
195 	/* Buffer to hold error message */
196 	char	   *errormsg_buf;
197 
198 	/*
199 	 * Set at the end of recovery: the start point of a partial record at the
200 	 * end of WAL (InvalidXLogRecPtr if there wasn't one), and the start
201 	 * location of its first contrecord that went missing.
202 	 */
203 	XLogRecPtr	abortedRecPtr;
204 	XLogRecPtr	missingContrecPtr;
205 	/* Set when XLP_FIRST_IS_OVERWRITE_CONTRECORD is found */
206 	XLogRecPtr	overwrittenRecPtr;
207 };
208 
209 /* Get a new XLogReader */
210 extern XLogReaderState *XLogReaderAllocate(int wal_segment_size,
211 										   XLogPageReadCB pagereadfunc,
212 										   void *private_data);
213 
214 /* Free an XLogReader */
215 extern void XLogReaderFree(XLogReaderState *state);
216 
217 /* Read the next XLog record. Returns NULL on end-of-WAL or failure */
218 extern struct XLogRecord *XLogReadRecord(XLogReaderState *state,
219 										 XLogRecPtr recptr, char **errormsg);
220 
221 /* Validate a page */
222 extern bool XLogReaderValidatePageHeader(XLogReaderState *state,
223 										 XLogRecPtr recptr, char *phdr);
224 
225 /* Invalidate read state */
226 extern void XLogReaderInvalReadState(XLogReaderState *state);
227 
228 #ifdef FRONTEND
229 extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr);
230 #endif							/* FRONTEND */
231 
232 /* Functions for decoding an XLogRecord */
233 
234 extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record,
235 							 char **errmsg);
236 
237 #define XLogRecGetTotalLen(decoder) ((decoder)->decoded_record->xl_tot_len)
238 #define XLogRecGetPrev(decoder) ((decoder)->decoded_record->xl_prev)
239 #define XLogRecGetInfo(decoder) ((decoder)->decoded_record->xl_info)
240 #define XLogRecGetRmid(decoder) ((decoder)->decoded_record->xl_rmid)
241 #define XLogRecGetXid(decoder) ((decoder)->decoded_record->xl_xid)
242 #define XLogRecGetOrigin(decoder) ((decoder)->record_origin)
243 #define XLogRecGetData(decoder) ((decoder)->main_data)
244 #define XLogRecGetDataLen(decoder) ((decoder)->main_data_len)
245 #define XLogRecHasAnyBlockRefs(decoder) ((decoder)->max_block_id >= 0)
246 #define XLogRecHasBlockRef(decoder, block_id) \
247 	((decoder)->blocks[block_id].in_use)
248 #define XLogRecHasBlockImage(decoder, block_id) \
249 	((decoder)->blocks[block_id].has_image)
250 #define XLogRecBlockImageApply(decoder, block_id) \
251 	((decoder)->blocks[block_id].apply_image)
252 
253 extern bool RestoreBlockImage(XLogReaderState *recoder, uint8 block_id, char *dst);
254 extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len);
255 extern bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id,
256 							   RelFileNode *rnode, ForkNumber *forknum,
257 							   BlockNumber *blknum);
258 
259 #endif							/* XLOGREADER_H */
260