Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0dc8ead

Browse files
committed
Refactor WAL file-reading code into WALRead()
XLogReader, walsender and pg_waldump all had their own routines to readdata from WAL files to memory, with slightly different approachesaccording to the particular conditions of each environment. There's alot of commonality, so we can refactor that into a single routineWALRead in XLogReader, and move the differences to a separate (simpler)callback that just opens the next WAL-segment. This results in aclearer (ahem) code flow.The error reporting needs are covered by filling in a new error-infostruct, 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 usingpg_pread().Author: Antonin Houska, with contributions from Álvaro HerreraReviewed-by: Michaël Paquier, Kyotaro HoriguchiDiscussion:https://postgr.es/m/14984.1554998742@spoje.net
1 parent5883f5f commit0dc8ead

File tree

6 files changed

+387
-433
lines changed

6 files changed

+387
-433
lines changed

‎src/backend/access/transam/xlogreader.c

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
*/
1818
#include"postgres.h"
1919

20+
#include<unistd.h>
21+
2022
#include"access/transam.h"
2123
#include"access/xlog_internal.h"
2224
#include"access/xlogreader.h"
@@ -27,6 +29,7 @@
2729

2830
#ifndefFRONTEND
2931
#include"miscadmin.h"
32+
#include"pgstat.h"
3033
#include"utils/memutils.h"
3134
#endif
3235

@@ -208,7 +211,6 @@ WALOpenSegmentInit(WALOpenSegment *seg, WALSegmentContext *segcxt,
208211
{
209212
seg->ws_file=-1;
210213
seg->ws_segno=0;
211-
seg->ws_off=0;
212214
seg->ws_tli=0;
213215

214216
segcxt->ws_segsize=segsize;
@@ -295,8 +297,7 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
295297
* byte to cover the whole record header, or at least the part of it that
296298
* fits on the same page.
297299
*/
298-
readOff=ReadPageInternal(state,
299-
targetPagePtr,
300+
readOff=ReadPageInternal(state,targetPagePtr,
300301
Min(targetRecOff+SizeOfXLogRecord,XLOG_BLCKSZ));
301302
if (readOff<0)
302303
gotoerr;
@@ -556,7 +557,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
556557

557558
/* check whether we have all the requested data already */
558559
if (targetSegNo==state->seg.ws_segno&&
559-
targetPageOff==state->seg.ws_off&&reqLen <=state->readLen)
560+
targetPageOff==state->segoff&&reqLen <=state->readLen)
560561
returnstate->readLen;
561562

562563
/*
@@ -627,7 +628,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
627628

628629
/* update read state information */
629630
state->seg.ws_segno=targetSegNo;
630-
state->seg.ws_off=targetPageOff;
631+
state->segoff=targetPageOff;
631632
state->readLen=readLen;
632633

633634
returnreadLen;
@@ -644,7 +645,7 @@ static void
644645
XLogReaderInvalReadState(XLogReaderState*state)
645646
{
646647
state->seg.ws_segno=0;
647-
state->seg.ws_off=0;
648+
state->segoff=0;
648649
state->readLen=0;
649650
}
650651

@@ -1015,6 +1016,99 @@ XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr)
10151016

10161017
#endif/* FRONTEND */
10171018

1019+
/*
1020+
* Read 'count' bytes into 'buf', starting at location 'startptr', from WAL
1021+
* fetched from timeline 'tli'.
1022+
*
1023+
* 'seg/segcxt' identify the last segment used. 'openSegment' is a callback
1024+
* to open the next segment, if necessary.
1025+
*
1026+
* Returns true if succeeded, false if an error occurs, in which case
1027+
* 'errinfo' receives error details.
1028+
*
1029+
* XXX probably this should be improved to suck data directly from the
1030+
* WAL buffers when possible.
1031+
*/
1032+
bool
1033+
WALRead(char*buf,XLogRecPtrstartptr,Sizecount,TimeLineIDtli,
1034+
WALOpenSegment*seg,WALSegmentContext*segcxt,
1035+
WALSegmentOpenopenSegment,WALReadError*errinfo)
1036+
{
1037+
char*p;
1038+
XLogRecPtrrecptr;
1039+
Sizenbytes;
1040+
1041+
p=buf;
1042+
recptr=startptr;
1043+
nbytes=count;
1044+
1045+
while (nbytes>0)
1046+
{
1047+
uint32startoff;
1048+
intsegbytes;
1049+
intreadbytes;
1050+
1051+
startoff=XLogSegmentOffset(recptr,segcxt->ws_segsize);
1052+
1053+
/*
1054+
* If the data we want is not in a segment we have open, close what we
1055+
* have (if anything) and open the next one, using the caller's
1056+
* provided openSegment callback.
1057+
*/
1058+
if (seg->ws_file<0||
1059+
!XLByteInSeg(recptr,seg->ws_segno,segcxt->ws_segsize)||
1060+
tli!=seg->ws_tli)
1061+
{
1062+
XLogSegNonextSegNo;
1063+
1064+
if (seg->ws_file >=0)
1065+
close(seg->ws_file);
1066+
1067+
XLByteToSeg(recptr,nextSegNo,segcxt->ws_segsize);
1068+
seg->ws_file=openSegment(nextSegNo,segcxt,&tli);
1069+
1070+
/* Update the current segment info. */
1071+
seg->ws_tli=tli;
1072+
seg->ws_segno=nextSegNo;
1073+
}
1074+
1075+
/* How many bytes are within this segment? */
1076+
if (nbytes> (segcxt->ws_segsize-startoff))
1077+
segbytes=segcxt->ws_segsize-startoff;
1078+
else
1079+
segbytes=nbytes;
1080+
1081+
#ifndefFRONTEND
1082+
pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
1083+
#endif
1084+
1085+
/* Reset errno first; eases reporting non-errno-affecting errors */
1086+
errno=0;
1087+
readbytes=pg_pread(seg->ws_file,p,segbytes, (off_t)startoff);
1088+
1089+
#ifndefFRONTEND
1090+
pgstat_report_wait_end();
1091+
#endif
1092+
1093+
if (readbytes <=0)
1094+
{
1095+
errinfo->wre_errno=errno;
1096+
errinfo->wre_req=segbytes;
1097+
errinfo->wre_read=readbytes;
1098+
errinfo->wre_off=startoff;
1099+
errinfo->wre_seg=*seg;
1100+
return false;
1101+
}
1102+
1103+
/* Update state for read */
1104+
recptr+=readbytes;
1105+
nbytes-=readbytes;
1106+
p+=readbytes;
1107+
}
1108+
1109+
return true;
1110+
}
1111+
10181112
/* ----------------------------------------
10191113
* Functions for decoding the data and block references in a record.
10201114
* ----------------------------------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp