Split out XLog reading as an independent facility

This new facility can not only be used by xlog.c to carry out crash
recovery, but also by external programs.  By supplying a function to
read XLog pages from somewhere, all the WAL reading can be used for
completely different purposes.

For the standard backend use, the behavior should be pretty much the
same as previously.  As for non-backend programs, an hypothetical
pg_xlogdump program is now closer to reality, but some more backend
support is still necessary.

This patch was originally submitted by Andres Freund in a different
form, but Heikki Linnakangas opted for and authored another design of
the concept.  Andres has advanced the patch since Heikki's initial
version.  Review and some (mostly cosmetics) changes by me.
This commit is contained in:
Alvaro Herrera 2013-01-16 16:12:53 -03:00
parent 8606dd8190
commit 7fcbf6a405
5 changed files with 1268 additions and 712 deletions

View File

@ -14,7 +14,7 @@ include $(top_builddir)/src/Makefile.global
OBJS = clog.o transam.o varsup.o xact.o rmgr.o slru.o subtrans.o multixact.o \
timeline.o twophase.o twophase_rmgr.o xlog.o xlogarchive.o xlogfuncs.o \
xlogutils.o
xlogreader.o xlogutils.o
include $(top_srcdir)/src/backend/common.mk

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,12 +4,13 @@ AVAIL_LANGUAGES = de es fr ja pt_BR tr zh_CN zh_TW
GETTEXT_FILES = + gettext-files
GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) \
GUC_check_errmsg GUC_check_errdetail GUC_check_errhint \
write_stderr yyerror parser_yyerror
write_stderr yyerror parser_yyerror report_invalid_record
GETTEXT_FLAGS = $(BACKEND_COMMON_GETTEXT_FLAGS) \
GUC_check_errmsg:1:c-format \
GUC_check_errdetail:1:c-format \
GUC_check_errhint:1:c-format \
write_stderr:1:c-format
write_stderr:1:c-format \
report_invalid_record:2:c-format
gettext-files: distprep
find $(srcdir)/ $(srcdir)/../port/ -name '*.c' -print | LC_ALL=C sort >$@

View File

@ -0,0 +1,116 @@
/*-------------------------------------------------------------------------
*
* xlogreader.h
* Definitions for the generic XLog reading facility
*
* Portions Copyright (c) 2013, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/include/access/xlogreader.h
*
* NOTES
* See the definition of the XLogReaderState struct for instructions on
* how to use the XLogReader infrastructure.
*
* The basic idea is to allocate an XLogReaderState via
* XLogReaderAllocate(), and call XLogReadRecord() until it returns NULL.
*-------------------------------------------------------------------------
*/
#ifndef XLOGREADER_H
#define XLOGREADER_H
#include "access/xlog_internal.h"
typedef struct XLogReaderState XLogReaderState;
/* Function type definition for the read_page callback */
typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader,
XLogRecPtr targetPagePtr,
int reqLen,
char *readBuf,
TimeLineID *pageTLI);
struct XLogReaderState
{
/* ----------------------------------------
* Public parameters
* ----------------------------------------
*/
/*
* Data input callback (mandatory).
*
* This callback shall read at least reqLen valid bytes of the xlog page
* starting at targetPagePtr, and store them in readBuf. The callback
* shall return the number of bytes read (never more than XLOG_BLCKSZ), or
* -1 on failure. The callback shall sleep, if necessary, to wait for the
* requested bytes to become available. The callback will not be invoked
* again for the same page unless more than the returned number of bytes
* are necessary.
*
* *pageTLI should be set to the TLI of the file the page was read from.
* It is currently used only for error reporting purposes, to reconstruct
* the name of the WAL file where an error occurred.
*/
XLogPageReadCB read_page;
/*
* System identifier of the xlog files we're about to read. Set to zero
* (the default value) if unknown or unimportant.
*/
uint64 system_identifier;
/*
* Opaque data for callbacks to use. Not used by XLogReader.
*/
void *private_data;
/*
* Start and end point of last record read. EndRecPtr is also used as the
* position to read next, if XLogReadRecord receives an invalid recptr.
*/
XLogRecPtr ReadRecPtr; /* start of last record read */
XLogRecPtr EndRecPtr; /* end+1 of last record read */
/* ----------------------------------------
* private/internal state
* ----------------------------------------
*/
/* Buffer for currently read page (XLOG_BLCKSZ bytes) */
char *readBuf;
/* last read segment, segment offset, read length, TLI */
XLogSegNo readSegNo;
uint32 readOff;
uint32 readLen;
TimeLineID readPageTLI;
/* beginning of last page read, and its TLI */
XLogRecPtr latestPagePtr;
TimeLineID latestPageTLI;
/* Buffer for current ReadRecord result (expandable) */
char *readRecordBuf;
uint32 readRecordBufSize;
/* Buffer to hold error message */
char *errormsg_buf;
};
/* Get a new XLogReader */
extern XLogReaderState *XLogReaderAllocate(XLogPageReadCB pagereadfunc,
void *private_data);
/* Free an XLogReader */
extern void XLogReaderFree(XLogReaderState *state);
/* Read the next XLog record. Returns NULL on end-of-WAL or failure */
extern struct XLogRecord *XLogReadRecord(XLogReaderState *state,
XLogRecPtr recptr, char **errormsg);
#ifdef FRONTEND
extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr);
#endif /* FRONTEND */
#endif /* XLOGREADER_H */