Make XLog storage extensible

and allow extensions to override it
For now, it extends on `pread` and `pwrite` from/into segment files.
This is the minimum we need for full XLog encryption with pg_de.
This commit is contained in:
Andrew Pogrebnoy 2024-04-24 19:59:14 +03:00 committed by Zsolt Parragi
parent 4a3f56c5f8
commit 8e1dd620fb
6 changed files with 50 additions and 5 deletions

View File

@ -61,6 +61,7 @@
#include "access/xloginsert.h"
#include "access/xlogreader.h"
#include "access/xlogrecovery.h"
#include "access/xlog_smgr.h"
#include "access/xlogutils.h"
#include "backup/basebackup.h"
#include "catalog/catversion.h"
@ -2442,7 +2443,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
INSTR_TIME_SET_ZERO(start);
pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE);
written = pg_pwrite(openLogFile, from, nleft, startoffset);
written = xlog_smgr->seg_write(openLogFile, from, nleft, startoffset);
pgstat_report_wait_end();
/*

View File

@ -29,6 +29,7 @@
#include "access/xlog_internal.h"
#include "access/xlogreader.h"
#include "access/xlogrecord.h"
#include "access/xlog_smgr.h"
#include "catalog/pg_control.h"
#include "common/pg_lzcompress.h"
#include "replication/origin.h"
@ -63,6 +64,21 @@ static void WALOpenSegmentInit(WALOpenSegment *seg, WALSegmentContext *segcxt,
*/
#define DEFAULT_DECODE_BUFFER_SIZE (64 * 1024)
/*
* XLog storage manager
*
* TODO: should be in xlog.c or new xlog_smgr.c ?
* Now it's here because pg_rewind and other tools compile only
* w/ xlogreader.c
*/
XLogSmgr *xlog_smgr = &xlog_smgr_standard;
void
SetXLogSmgr(XLogSmgr *xlsmgr)
{
xlog_smgr = xlsmgr;
}
/*
* Construct a string in state->errormsg_buf explaining what's wrong with
* the current record being read.
@ -1557,7 +1573,7 @@ WALRead(XLogReaderState *state,
/* Reset errno first; eases reporting non-errno-affecting errors */
errno = 0;
readbytes = pg_pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
readbytes = xlog_smgr->seg_read(state->seg.ws_file, p, segbytes, (off_t) startoff);
#ifndef FRONTEND
pgstat_report_wait_end();

View File

@ -39,6 +39,7 @@
#include "access/xlogprefetcher.h"
#include "access/xlogreader.h"
#include "access/xlogrecovery.h"
#include "access/xlog_smgr.h"
#include "access/xlogutils.h"
#include "backup/basebackup.h"
#include "catalog/pg_control.h"
@ -3397,7 +3398,7 @@ retry:
readOff = targetPageOff;
pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
r = xlog_smgr->seg_read(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
if (r != XLOG_BLCKSZ)
{
char fname[MAXFNAMELEN];

View File

@ -57,6 +57,7 @@
#include "access/xlog_internal.h"
#include "access/xlogarchive.h"
#include "access/xlogrecovery.h"
#include "access/xlog_smgr.h"
#include "catalog/pg_authid.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
@ -941,7 +942,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli)
/* OK to write the logs */
errno = 0;
byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff);
byteswritten = xlog_smgr->seg_write(recvFile, buf, segbytes, (off_t) startoff);
if (byteswritten <= 0)
{
char xlogfname[MAXFNAMELEN];

View File

@ -78,8 +78,10 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
#define XLP_BKP_REMOVABLE 0x0004
/* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */
#define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008
/* The page is encrypted */
#define XLP_ENCRYPTED 0x0010
/* All defined flag bits in xlp_info (used for validity checking of header) */
#define XLP_ALL_FLAGS 0x000F
#define XLP_ALL_FLAGS 0x001F
#define XLogPageHeaderSize(hdr) \
(((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)

View File

@ -0,0 +1,24 @@
#ifndef XLOG_SMGR_H
#define XLOG_SMGR_H
#include "postgres.h"
#include <unistd.h>
/* XLog storage manager interface */
typedef struct XLogSmgr {
ssize_t (*seg_read) (int fd, void *buf, size_t count, off_t offset);
ssize_t (*seg_write) (int fd, const void *buf, size_t count, off_t offset);
} XLogSmgr;
/* Default (standard) XLog storage manager */
static const XLogSmgr xlog_smgr_standard = {
.seg_read = pg_pread,
.seg_write = pg_pwrite,
};
extern XLogSmgr *xlog_smgr;
extern void SetXLogSmgr(XLogSmgr *xlsmgr);
#endif /* XLOG_SMGR_H */