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
30typedef struct XLogReaderState XLogReaderState;
31
32/* Function type definition for the read_page callback */
33typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader,
34 XLogRecPtr targetPagePtr,
35 int reqLen,
36 XLogRecPtr targetRecPtr,
37 char *readBuf,
38 TimeLineID *pageTLI);
39
40typedef 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
69struct 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/* Get a new XLogReader */
200extern XLogReaderState *XLogReaderAllocate(int wal_segment_size,
201 XLogPageReadCB pagereadfunc,
202 void *private_data);
203
204/* Free an XLogReader */
205extern void XLogReaderFree(XLogReaderState *state);
206
207/* Read the next XLog record. Returns NULL on end-of-WAL or failure */
208extern struct XLogRecord *XLogReadRecord(XLogReaderState *state,
209 XLogRecPtr recptr, char **errormsg);
210
211/* Validate a page */
212extern bool XLogReaderValidatePageHeader(XLogReaderState *state,
213 XLogRecPtr recptr, char *phdr);
214
215/* Invalidate read state */
216extern void XLogReaderInvalReadState(XLogReaderState *state);
217
218#ifdef FRONTEND
219extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr);
220#endif /* FRONTEND */
221
222/* Functions for decoding an XLogRecord */
223
224extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record,
225 char **errmsg);
226
227#define XLogRecGetTotalLen(decoder) ((decoder)->decoded_record->xl_tot_len)
228#define XLogRecGetPrev(decoder) ((decoder)->decoded_record->xl_prev)
229#define XLogRecGetInfo(decoder) ((decoder)->decoded_record->xl_info)
230#define XLogRecGetRmid(decoder) ((decoder)->decoded_record->xl_rmid)
231#define XLogRecGetXid(decoder) ((decoder)->decoded_record->xl_xid)
232#define XLogRecGetOrigin(decoder) ((decoder)->record_origin)
233#define XLogRecGetData(decoder) ((decoder)->main_data)
234#define XLogRecGetDataLen(decoder) ((decoder)->main_data_len)
235#define XLogRecHasAnyBlockRefs(decoder) ((decoder)->max_block_id >= 0)
236#define XLogRecHasBlockRef(decoder, block_id) \
237 ((decoder)->blocks[block_id].in_use)
238#define XLogRecHasBlockImage(decoder, block_id) \
239 ((decoder)->blocks[block_id].has_image)
240#define XLogRecBlockImageApply(decoder, block_id) \
241 ((decoder)->blocks[block_id].apply_image)
242
243extern bool RestoreBlockImage(XLogReaderState *recoder, uint8 block_id, char *dst);
244extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len);
245extern bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id,
246 RelFileNode *rnode, ForkNumber *forknum,
247 BlockNumber *blknum);
248
249#endif /* XLOGREADER_H */
250