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

Commitb5ec22b

Browse files
committed
Fix issue with WAL archiving in standby.
Previously, walreceiver always closed the currently-opened WAL segmentand created its archive notification file, after it finished writingthe current segment up and received any WAL data that should bewritten into the next segment. If walreceiver exited just beforeany WAL data in the next segment arrived at standby, it did notcreate the archive notification file of the current segmenteven though that's known completed. This behavior could causeWAL archiving of the segment to be delayed until subsequentrestartpoints or checkpoints created its notification file.To fix the issue, this commit changes walreceiver so that it createsan archive notification file of a current WAL segment immediatelyif that's known completed before receiving next WAL data.Back-patch to all supported branches.Reported-by: Kyotaro HoriguchiAuthor: Fujii MasaoReviewed-by: Kyotaro HoriguchiDiscussion:https://postgr.es/m/20200630.165503.1465894182551545886.horikyota.ntt@gmail.com
1 parent52c300d commitb5ec22b

File tree

1 file changed

+62
-37
lines changed

1 file changed

+62
-37
lines changed

‎src/backend/replication/walreceiver.c

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ static void WalRcvDie(int code, Datum arg);
125125
staticvoidXLogWalRcvProcessMsg(unsignedchartype,char*buf,Sizelen);
126126
staticvoidXLogWalRcvWrite(char*buf,Sizenbytes,XLogRecPtrrecptr);
127127
staticvoidXLogWalRcvFlush(booldying);
128+
staticvoidXLogWalRcvClose(XLogRecPtrrecptr);
128129
staticvoidXLogWalRcvSendReply(boolforce,boolrequestReply);
129130
staticvoidXLogWalRcvSendHSFeedback(boolimmed);
130131
staticvoidProcessWalSndrMessage(XLogRecPtrwalEnd,TimestampTzsendTime);
@@ -883,47 +884,16 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
883884
{
884885
intsegbytes;
885886

886-
if (recvFile<0|| !XLByteInSeg(recptr,recvSegNo,wal_segment_size))
887-
{
888-
booluse_existent;
889-
890-
/*
891-
* fsync() and close current file before we switch to next one. We
892-
* would otherwise have to reopen this file to fsync it later
893-
*/
894-
if (recvFile >=0)
895-
{
896-
charxlogfname[MAXFNAMELEN];
897-
898-
XLogWalRcvFlush(false);
899-
900-
XLogFileName(xlogfname,recvFileTLI,recvSegNo,wal_segment_size);
901-
902-
/*
903-
* XLOG segment files will be re-read by recovery in startup
904-
* process soon, so we don't advise the OS to release cache
905-
* pages associated with the file like XLogFileClose() does.
906-
*/
907-
if (close(recvFile)!=0)
908-
ereport(PANIC,
909-
(errcode_for_file_access(),
910-
errmsg("could not close log segment %s: %m",
911-
xlogfname)));
887+
/* Close the current segment if it's completed */
888+
if (recvFile >=0&& !XLByteInSeg(recptr,recvSegNo,wal_segment_size))
889+
XLogWalRcvClose(recptr);
912890

913-
/*
914-
* Create .done file forcibly to prevent the streamed segment
915-
* from being archived later.
916-
*/
917-
if (XLogArchiveMode!=ARCHIVE_MODE_ALWAYS)
918-
XLogArchiveForceDone(xlogfname);
919-
else
920-
XLogArchiveNotify(xlogfname);
921-
}
922-
recvFile=-1;
891+
if (recvFile<0)
892+
{
893+
booluse_existent= true;
923894

924895
/* Create/use new log file */
925896
XLByteToSeg(recptr,recvSegNo,wal_segment_size);
926-
use_existent= true;
927897
recvFile=XLogFileInit(recvSegNo,&use_existent, true);
928898
recvFileTLI=ThisTimeLineID;
929899
}
@@ -970,6 +940,15 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
970940

971941
/* Update shared-memory status */
972942
pg_atomic_write_u64(&WalRcv->writtenUpto,LogstreamResult.Write);
943+
944+
/*
945+
* Close the current segment if it's fully written up in the last cycle of
946+
* the loop, to create its archive notification file soon. Otherwise WAL
947+
* archiving of the segment will be delayed until any data in the next
948+
* segment is received and written.
949+
*/
950+
if (recvFile >=0&& !XLByteInSeg(recptr,recvSegNo,wal_segment_size))
951+
XLogWalRcvClose(recptr);
973952
}
974953

975954
/*
@@ -1023,6 +1002,52 @@ XLogWalRcvFlush(bool dying)
10231002
}
10241003
}
10251004

1005+
/*
1006+
* Close the current segment.
1007+
*
1008+
* Flush the segment to disk before closing it. Otherwise we have to
1009+
* reopen and fsync it later.
1010+
*
1011+
* Create an archive notification file since the segment is known completed.
1012+
*/
1013+
staticvoid
1014+
XLogWalRcvClose(XLogRecPtrrecptr)
1015+
{
1016+
charxlogfname[MAXFNAMELEN];
1017+
1018+
Assert(recvFile >=0&& !XLByteInSeg(recptr,recvSegNo,wal_segment_size));
1019+
1020+
/*
1021+
* fsync() and close current file before we switch to next one. We would
1022+
* otherwise have to reopen this file to fsync it later
1023+
*/
1024+
XLogWalRcvFlush(false);
1025+
1026+
XLogFileName(xlogfname,recvFileTLI,recvSegNo,wal_segment_size);
1027+
1028+
/*
1029+
* XLOG segment files will be re-read by recovery in startup process soon,
1030+
* so we don't advise the OS to release cache pages associated with the
1031+
* file like XLogFileClose() does.
1032+
*/
1033+
if (close(recvFile)!=0)
1034+
ereport(PANIC,
1035+
(errcode_for_file_access(),
1036+
errmsg("could not close log segment %s: %m",
1037+
xlogfname)));
1038+
1039+
/*
1040+
* Create .done file forcibly to prevent the streamed segment from being
1041+
* archived later.
1042+
*/
1043+
if (XLogArchiveMode!=ARCHIVE_MODE_ALWAYS)
1044+
XLogArchiveForceDone(xlogfname);
1045+
else
1046+
XLogArchiveNotify(xlogfname);
1047+
1048+
recvFile=-1;
1049+
}
1050+
10261051
/*
10271052
* Send reply message to primary, indicating our current WAL locations, oldest
10281053
* xmin and the current time.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp