Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
xlogreader.h445 linesDownload Raw Back to access
1/*-------------------------------------------------------------------------2 *3 * xlogreader.h4 *		Definitions for the generic XLog reading facility5 *6 * Portions Copyright (c) 2013-2023, PostgreSQL Global Development Group7 *8 * IDENTIFICATION9 *		src/include/access/xlogreader.h10 *11 * NOTES12 *		See the definition of the XLogReaderState struct for instructions on13 *		how to use the XLogReader infrastructure.14 *15 *		The basic idea is to allocate an XLogReaderState via16 *		XLogReaderAllocate(), position the reader to the first record with17 *		XLogBeginRead() or XLogFindNextRecord(), and call XLogReadRecord()18 *		until it returns NULL.19 *20 *		Callers supply a page_read callback if they want to call21 *		XLogReadRecord or XLogFindNextRecord; it can be passed in as NULL22 *		otherwise.  The WALRead function can be used as a helper to write23 *		page_read callbacks, but it is not mandatory; callers that use it,24 *		must supply segment_open callbacks.  The segment_close callback25 *		must always be supplied.26 *27 *		After reading a record with XLogReadRecord(), it's decomposed into28 *		the per-block and main data parts, and the parts can be accessed29 *		with the XLogRec* macros and functions. You can also decode a30 *		record that's already constructed in memory, without reading from31 *		disk, by calling the DecodeXLogRecord() function.32 *-------------------------------------------------------------------------33 */34#ifndef XLOGREADER_H35#define XLOGREADER_H36 37#ifndef FRONTEND38#include "access/transam.h"39#endif40 41#include "access/xlogrecord.h"42#include "storage/buf.h"43 44/* WALOpenSegment represents a WAL segment being read. */45typedef struct WALOpenSegment46{47	int			ws_file;		/* segment file descriptor */48	XLogSegNo	ws_segno;		/* segment number */49	TimeLineID	ws_tli;			/* timeline ID of the currently open file */50} WALOpenSegment;51 52/* WALSegmentContext carries context information about WAL segments to read */53typedef struct WALSegmentContext54{55	char		ws_dir[MAXPGPATH];56	int			ws_segsize;57} WALSegmentContext;58 59typedef struct XLogReaderState XLogReaderState;60 61/* Function type definitions for various xlogreader interactions */62typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader,63							   XLogRecPtr targetPagePtr,64							   int reqLen,65							   XLogRecPtr targetRecPtr,66							   char *readBuf);67typedef void (*WALSegmentOpenCB) (XLogReaderState *xlogreader,68								  XLogSegNo nextSegNo,69								  TimeLineID *tli_p);70typedef void (*WALSegmentCloseCB) (XLogReaderState *xlogreader);71 72typedef struct XLogReaderRoutine73{74	/*75	 * Data input callback76	 *77	 * This callback shall read at least reqLen valid bytes of the xlog page78	 * starting at targetPagePtr, and store them in readBuf.  The callback79	 * shall return the number of bytes read (never more than XLOG_BLCKSZ), or80	 * -1 on failure.  The callback shall sleep, if necessary, to wait for the81	 * requested bytes to become available.  The callback will not be invoked82	 * again for the same page unless more than the returned number of bytes83	 * are needed.84	 *85	 * targetRecPtr is the position of the WAL record we're reading.  Usually86	 * it is equal to targetPagePtr + reqLen, but sometimes xlogreader needs87	 * to read and verify the page or segment header, before it reads the88	 * actual WAL record it's interested in.  In that case, targetRecPtr can89	 * be used to determine which timeline to read the page from.90	 *91	 * The callback shall set ->seg.ws_tli to the TLI of the file the page was92	 * read from.93	 */94	XLogPageReadCB page_read;95 96	/*97	 * Callback to open the specified WAL segment for reading.  ->seg.ws_file98	 * shall be set to the file descriptor of the opened segment.  In case of99	 * failure, an error shall be raised by the callback and it shall not100	 * return.101	 *102	 * "nextSegNo" is the number of the segment to be opened.103	 *104	 * "tli_p" is an input/output argument. WALRead() uses it to pass the105	 * timeline in which the new segment should be found, but the callback can106	 * use it to return the TLI that it actually opened.107	 */108	WALSegmentOpenCB segment_open;109 110	/*111	 * WAL segment close callback.  ->seg.ws_file shall be set to a negative112	 * number.113	 */114	WALSegmentCloseCB segment_close;115} XLogReaderRoutine;116 117#define XL_ROUTINE(...) &(XLogReaderRoutine){__VA_ARGS__}118 119typedef struct120{121	/* Is this block ref in use? */122	bool		in_use;123 124	/* Identify the block this refers to */125	RelFileLocator rlocator;126	ForkNumber	forknum;127	BlockNumber blkno;128 129	/* Prefetching workspace. */130	Buffer		prefetch_buffer;131 132	/* copy of the fork_flags field from the XLogRecordBlockHeader */133	uint8		flags;134 135	/* Information on full-page image, if any */136	bool		has_image;		/* has image, even for consistency checking */137	bool		apply_image;	/* has image that should be restored */138	char	   *bkp_image;139	uint16		hole_offset;140	uint16		hole_length;141	uint16		bimg_len;142	uint8		bimg_info;143 144	/* Buffer holding the rmgr-specific data associated with this block */145	bool		has_data;146	char	   *data;147	uint16		data_len;148	uint16		data_bufsz;149} DecodedBkpBlock;150 151/*152 * The decoded contents of a record.  This occupies a contiguous region of153 * memory, with main_data and blocks[n].data pointing to memory after the154 * members declared here.155 */156typedef struct DecodedXLogRecord157{158	/* Private member used for resource management. */159	size_t		size;			/* total size of decoded record */160	bool		oversized;		/* outside the regular decode buffer? */161	struct DecodedXLogRecord *next; /* decoded record queue link */162 163	/* Public members. */164	XLogRecPtr	lsn;			/* location */165	XLogRecPtr	next_lsn;		/* location of next record */166	XLogRecord	header;			/* header */167	RepOriginId record_origin;168	TransactionId toplevel_xid; /* XID of top-level transaction */169	char	   *main_data;		/* record's main data portion */170	uint32		main_data_len;	/* main data portion's length */171	int			max_block_id;	/* highest block_id in use (-1 if none) */172	DecodedBkpBlock blocks[FLEXIBLE_ARRAY_MEMBER];173} DecodedXLogRecord;174 175struct XLogReaderState176{177	/*178	 * Operational callbacks179	 */180	XLogReaderRoutine routine;181 182	/* ----------------------------------------183	 * Public parameters184	 * ----------------------------------------185	 */186 187	/*188	 * System identifier of the xlog files we're about to read.  Set to zero189	 * (the default value) if unknown or unimportant.190	 */191	uint64		system_identifier;192 193	/*194	 * Opaque data for callbacks to use.  Not used by XLogReader.195	 */196	void	   *private_data;197 198	/*199	 * Start and end point of last record read.  EndRecPtr is also used as the200	 * position to read next.  Calling XLogBeginRead() sets EndRecPtr to the201	 * starting position and ReadRecPtr to invalid.202	 *203	 * Start and end point of last record returned by XLogReadRecord().  These204	 * are also available as record->lsn and record->next_lsn.205	 */206	XLogRecPtr	ReadRecPtr;		/* start of last record read */207	XLogRecPtr	EndRecPtr;		/* end+1 of last record read */208 209	/*210	 * Set at the end of recovery: the start point of a partial record at the211	 * end of WAL (InvalidXLogRecPtr if there wasn't one), and the start212	 * location of its first contrecord that went missing.213	 */214	XLogRecPtr	abortedRecPtr;215	XLogRecPtr	missingContrecPtr;216	/* Set when XLP_FIRST_IS_OVERWRITE_CONTRECORD is found */217	XLogRecPtr	overwrittenRecPtr;218 219 220	/* ----------------------------------------221	 * Decoded representation of current record222	 *223	 * Use XLogRecGet* functions to investigate the record; these fields224	 * should not be accessed directly.225	 * ----------------------------------------226	 * Start and end point of the last record read and decoded by227	 * XLogReadRecordInternal().  NextRecPtr is also used as the position to228	 * decode next.  Calling XLogBeginRead() sets NextRecPtr and EndRecPtr to229	 * the requested starting position.230	 */231	XLogRecPtr	DecodeRecPtr;	/* start of last record decoded */232	XLogRecPtr	NextRecPtr;		/* end+1 of last record decoded */233	XLogRecPtr	PrevRecPtr;		/* start of previous record decoded */234 235	/* Last record returned by XLogReadRecord(). */236	DecodedXLogRecord *record;237 238	/* ----------------------------------------239	 * private/internal state240	 * ----------------------------------------241	 */242 243	/*244	 * Buffer for decoded records.  This is a circular buffer, though245	 * individual records can't be split in the middle, so some space is often246	 * wasted at the end.  Oversized records that don't fit in this space are247	 * allocated separately.248	 */249	char	   *decode_buffer;250	size_t		decode_buffer_size;251	bool		free_decode_buffer; /* need to free? */252	char	   *decode_buffer_head; /* data is read from the head */253	char	   *decode_buffer_tail; /* new data is written at the tail */254 255	/*256	 * Queue of records that have been decoded.  This is a linked list that257	 * usually consists of consecutive records in decode_buffer, but may also258	 * contain oversized records allocated with palloc().259	 */260	DecodedXLogRecord *decode_queue_head;	/* oldest decoded record */261	DecodedXLogRecord *decode_queue_tail;	/* newest decoded record */262 263	/*264	 * Buffer for currently read page (XLOG_BLCKSZ bytes, valid up to at least265	 * readLen bytes)266	 */267	char	   *readBuf;268	uint32		readLen;269 270	/* last read XLOG position for data currently in readBuf */271	WALSegmentContext segcxt;272	WALOpenSegment seg;273	uint32		segoff;274 275	/*276	 * beginning of prior page read, and its TLI.  Doesn't necessarily277	 * correspond to what's in readBuf; used for timeline sanity checks.278	 */279	XLogRecPtr	latestPagePtr;280	TimeLineID	latestPageTLI;281 282	/* beginning of the WAL record being read. */283	XLogRecPtr	currRecPtr;284	/* timeline to read it from, 0 if a lookup is required */285	TimeLineID	currTLI;286 287	/*288	 * Safe point to read to in currTLI if current TLI is historical289	 * (tliSwitchPoint) or InvalidXLogRecPtr if on current timeline.290	 *291	 * Actually set to the start of the segment containing the timeline switch292	 * that ends currTLI's validity, not the LSN of the switch its self, since293	 * we can't assume the old segment will be present.294	 */295	XLogRecPtr	currTLIValidUntil;296 297	/*298	 * If currTLI is not the most recent known timeline, the next timeline to299	 * read from when currTLIValidUntil is reached.300	 */301	TimeLineID	nextTLI;302 303	/*304	 * Buffer for current ReadRecord result (expandable), used when a record305	 * crosses a page boundary.306	 */307	char	   *readRecordBuf;308	uint32		readRecordBufSize;309 310	/* Buffer to hold error message */311	char	   *errormsg_buf;312	bool		errormsg_deferred;313 314	/*315	 * Flag to indicate to XLogPageReadCB that it should not block waiting for316	 * data.317	 */318	bool		nonblocking;319};320 321/*322 * Check if XLogNextRecord() has any more queued records or an error to return.323 */324static inline bool325XLogReaderHasQueuedRecordOrError(XLogReaderState *state)326{327	return (state->decode_queue_head != NULL) || state->errormsg_deferred;328}329 330/* Get a new XLogReader */331extern XLogReaderState *XLogReaderAllocate(int wal_segment_size,332										   const char *waldir,333										   XLogReaderRoutine *routine,334										   void *private_data);335 336/* Free an XLogReader */337extern void XLogReaderFree(XLogReaderState *state);338 339/* Optionally provide a circular decoding buffer to allow readahead. */340extern void XLogReaderSetDecodeBuffer(XLogReaderState *state,341									  void *buffer,342									  size_t size);343 344/* Position the XLogReader to given record */345extern void XLogBeginRead(XLogReaderState *state, XLogRecPtr RecPtr);346extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr);347 348/* Return values from XLogPageReadCB. */349typedef enum XLogPageReadResult350{351	XLREAD_SUCCESS = 0,			/* record is successfully read */352	XLREAD_FAIL = -1,			/* failed during reading a record */353	XLREAD_WOULDBLOCK = -2		/* nonblocking mode only, no data */354} XLogPageReadResult;355 356/* Read the next XLog record. Returns NULL on end-of-WAL or failure */357extern struct XLogRecord *XLogReadRecord(XLogReaderState *state,358										 char **errormsg);359 360/* Consume the next record or error. */361extern DecodedXLogRecord *XLogNextRecord(XLogReaderState *state,362										 char **errormsg);363 364/* Release the previously returned record, if necessary. */365extern XLogRecPtr XLogReleasePreviousRecord(XLogReaderState *state);366 367/* Try to read ahead, if there is data and space. */368extern DecodedXLogRecord *XLogReadAhead(XLogReaderState *state,369										bool nonblocking);370 371/* Validate a page */372extern bool XLogReaderValidatePageHeader(XLogReaderState *state,373										 XLogRecPtr recptr, char *phdr);374 375/* Forget error produced by XLogReaderValidatePageHeader(). */376extern void XLogReaderResetError(XLogReaderState *state);377 378/*379 * Error information from WALRead that both backend and frontend caller can380 * process.  Currently only errors from pg_pread can be reported.381 */382typedef struct WALReadError383{384	int			wre_errno;		/* errno set by the last pg_pread() */385	int			wre_off;		/* Offset we tried to read from. */386	int			wre_req;		/* Bytes requested to be read. */387	int			wre_read;		/* Bytes read by the last read(). */388	WALOpenSegment wre_seg;		/* Segment we tried to read from. */389} WALReadError;390 391extern bool WALRead(XLogReaderState *state,392					char *buf, XLogRecPtr startptr, Size count,393					TimeLineID tli, WALReadError *errinfo);394 395/* Functions for decoding an XLogRecord */396 397extern size_t DecodeXLogRecordRequiredSpace(size_t xl_tot_len);398extern bool DecodeXLogRecord(XLogReaderState *state,399							 DecodedXLogRecord *decoded,400							 XLogRecord *record,401							 XLogRecPtr lsn,402							 char **errormsg);403 404/*405 * Macros that provide access to parts of the record most recently returned by406 * XLogReadRecord() or XLogNextRecord().407 */408#define XLogRecGetTotalLen(decoder) ((decoder)->record->header.xl_tot_len)409#define XLogRecGetPrev(decoder) ((decoder)->record->header.xl_prev)410#define XLogRecGetInfo(decoder) ((decoder)->record->header.xl_info)411#define XLogRecGetRmid(decoder) ((decoder)->record->header.xl_rmid)412#define XLogRecGetXid(decoder) ((decoder)->record->header.xl_xid)413#define XLogRecGetOrigin(decoder) ((decoder)->record->record_origin)414#define XLogRecGetTopXid(decoder) ((decoder)->record->toplevel_xid)415#define XLogRecGetData(decoder) ((decoder)->record->main_data)416#define XLogRecGetDataLen(decoder) ((decoder)->record->main_data_len)417#define XLogRecHasAnyBlockRefs(decoder) ((decoder)->record->max_block_id >= 0)418#define XLogRecMaxBlockId(decoder) ((decoder)->record->max_block_id)419#define XLogRecGetBlock(decoder, i) (&(decoder)->record->blocks[(i)])420#define XLogRecHasBlockRef(decoder, block_id)			\421	(((decoder)->record->max_block_id >= (block_id)) &&	\422	 ((decoder)->record->blocks[block_id].in_use))423#define XLogRecHasBlockImage(decoder, block_id)		\424	((decoder)->record->blocks[block_id].has_image)425#define XLogRecBlockImageApply(decoder, block_id)		\426	((decoder)->record->blocks[block_id].apply_image)427#define XLogRecHasBlockData(decoder, block_id)		\428	((decoder)->record->blocks[block_id].has_data)429 430#ifndef FRONTEND431extern FullTransactionId XLogRecGetFullXid(XLogReaderState *record);432#endif433 434extern bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page);435extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len);436extern void XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id,437							   RelFileLocator *rlocator, ForkNumber *forknum,438							   BlockNumber *blknum);439extern bool XLogRecGetBlockTagExtended(XLogReaderState *record, uint8 block_id,440									   RelFileLocator *rlocator, ForkNumber *forknum,441									   BlockNumber *blknum,442									   Buffer *prefetch_buffer);443 444#endif							/* XLOGREADER_H */445 
codekingpro/portable-devtools · Team Ai