diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2019-11-25 15:04:54 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2019-11-25 15:04:54 -0300 |
commit | 0dc8ead46363fec6f621a12c7e1f889ba73b55a9 (patch) | |
tree | ae1eb1d20970c69eeac44e57a44f4315b5223ea0 /src/include/access/xlogreader.h | |
parent | 5883f5fe27d7b52c812dd0f8cbda67373a14c451 (diff) |
Refactor WAL file-reading code into WALRead()
XLogReader, walsender and pg_waldump all had their own routines to read
data from WAL files to memory, with slightly different approaches
according to the particular conditions of each environment. There's a
lot of commonality, so we can refactor that into a single routine
WALRead in XLogReader, and move the differences to a separate (simpler)
callback that just opens the next WAL-segment. This results in a
clearer (ahem) code flow.
The error reporting needs are covered by filling in a new error-info
struct, WALReadError, and it's the caller's responsibility to act on it.
The backend has WALReadRaiseError() to do so.
We no longer ever need to seek in this interface; switch to using
pg_pread().
Author: Antonin Houska, with contributions from Álvaro Herrera
Reviewed-by: Michaël Paquier, Kyotaro Horiguchi
Discussion: https://postgr.es/m/14984.1554998742@spoje.net
Diffstat (limited to 'src/include/access/xlogreader.h')
-rw-r--r-- | src/include/access/xlogreader.h | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h index 1bbee386e8d..0193611b7fd 100644 --- a/src/include/access/xlogreader.h +++ b/src/include/access/xlogreader.h @@ -36,7 +36,6 @@ typedef struct WALOpenSegment { int ws_file; /* segment file descriptor */ XLogSegNo ws_segno; /* segment number */ - uint32 ws_off; /* offset in the segment */ TimeLineID ws_tli; /* timeline ID of the currently open file */ } WALOpenSegment; @@ -168,6 +167,7 @@ struct XLogReaderState /* last read XLOG position for data currently in readBuf */ WALSegmentContext segcxt; WALOpenSegment seg; + uint32 segoff; /* * beginning of prior page read, and its TLI. Doesn't necessarily @@ -217,6 +217,24 @@ extern XLogReaderState *XLogReaderAllocate(int wal_segment_size, /* Free an XLogReader */ extern void XLogReaderFree(XLogReaderState *state); +/* + * Callback to open the specified WAL segment for reading. Returns a valid + * file descriptor when the file was opened successfully. + * + * "nextSegNo" is the number of the segment to be opened. + * + * "segcxt" is additional information about the segment. + * + * "tli_p" is an input/output argument. XLogRead() uses it to pass the + * timeline in which the new segment should be found, but the callback can use + * it to return the TLI that it actually opened. + * + * BasicOpenFile() is the preferred way to open the segment file in backend + * code, whereas open(2) should be used in frontend. + */ +typedef int (*WALSegmentOpen) (XLogSegNo nextSegNo, WALSegmentContext *segcxt, + TimeLineID *tli_p); + /* Initialize supporting structures */ extern void WALOpenSegmentInit(WALOpenSegment *seg, WALSegmentContext *segcxt, int segsize, const char *waldir); @@ -232,6 +250,25 @@ extern bool XLogReaderValidatePageHeader(XLogReaderState *state, #ifdef FRONTEND extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr); #endif /* FRONTEND */ + +/* + * Error information from WALRead that both backend and frontend caller can + * process. Currently only errors from pg_pread can be reported. + */ +typedef struct WALReadError +{ + int wre_errno; /* errno set by the last pg_pread() */ + int wre_off; /* Offset we tried to read from. */ + int wre_req; /* Bytes requested to be read. */ + int wre_read; /* Bytes read by the last read(). */ + WALOpenSegment wre_seg; /* Segment we tried to read from. */ +} WALReadError; + +extern bool WALRead(char *buf, XLogRecPtr startptr, Size count, + TimeLineID tli, WALOpenSegment *seg, + WALSegmentContext *segcxt, WALSegmentOpen openSegment, + WALReadError *errinfo); + /* Functions for decoding an XLogRecord */ extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, |