1 /*------------------------------------------------------------------------- 2 * 3 * xlogreader.h 4 * Definitions for the generic XLog reading facility 5 * 6 * Portions Copyright (c) 2013-2018, 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 /* Buffer for current ReadRecord result (expandable) */ 189 char *readRecordBuf; 190 uint32 readRecordBufSize; 191 192 /* Buffer to hold error message */ 193 char *errormsg_buf; 194 195 /* 196 * Set at the end of recovery: the start point of a partial record at the 197 * end of WAL (InvalidXLogRecPtr if there wasn't one), and the start 198 * location of its first contrecord that went missing. 199 */ 200 XLogRecPtr abortedRecPtr; 201 XLogRecPtr missingContrecPtr; 202 /* Set when XLP_FIRST_IS_OVERWRITE_CONTRECORD is found */ 203 XLogRecPtr overwrittenRecPtr; 204 }; 205 206 /* Get a new XLogReader */ 207 extern XLogReaderState *XLogReaderAllocate(int wal_segment_size, 208 XLogPageReadCB pagereadfunc, 209 void *private_data); 210 211 /* Free an XLogReader */ 212 extern void XLogReaderFree(XLogReaderState *state); 213 214 /* Read the next XLog record. Returns NULL on end-of-WAL or failure */ 215 extern struct XLogRecord *XLogReadRecord(XLogReaderState *state, 216 XLogRecPtr recptr, char **errormsg); 217 218 /* Validate a page */ 219 extern bool XLogReaderValidatePageHeader(XLogReaderState *state, 220 XLogRecPtr recptr, char *phdr); 221 222 /* Invalidate read state */ 223 extern void XLogReaderInvalReadState(XLogReaderState *state); 224 225 #ifdef FRONTEND 226 extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr); 227 #endif /* FRONTEND */ 228 229 /* Functions for decoding an XLogRecord */ 230 231 extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, 232 char **errmsg); 233 234 #define XLogRecGetTotalLen(decoder) ((decoder)->decoded_record->xl_tot_len) 235 #define XLogRecGetPrev(decoder) ((decoder)->decoded_record->xl_prev) 236 #define XLogRecGetInfo(decoder) ((decoder)->decoded_record->xl_info) 237 #define XLogRecGetRmid(decoder) ((decoder)->decoded_record->xl_rmid) 238 #define XLogRecGetXid(decoder) ((decoder)->decoded_record->xl_xid) 239 #define XLogRecGetOrigin(decoder) ((decoder)->record_origin) 240 #define XLogRecGetData(decoder) ((decoder)->main_data) 241 #define XLogRecGetDataLen(decoder) ((decoder)->main_data_len) 242 #define XLogRecHasAnyBlockRefs(decoder) ((decoder)->max_block_id >= 0) 243 #define XLogRecHasBlockRef(decoder, block_id) \ 244 ((decoder)->blocks[block_id].in_use) 245 #define XLogRecHasBlockImage(decoder, block_id) \ 246 ((decoder)->blocks[block_id].has_image) 247 #define XLogRecBlockImageApply(decoder, block_id) \ 248 ((decoder)->blocks[block_id].apply_image) 249 250 extern bool RestoreBlockImage(XLogReaderState *recoder, uint8 block_id, char *dst); 251 extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len); 252 extern bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, 253 RelFileNode *rnode, ForkNumber *forknum, 254 BlockNumber *blknum); 255 256 #endif /* XLOGREADER_H */ 257