diff options
-rw-r--r-- | src/backend/access/transam/xlogarchive.c | 59 | ||||
-rw-r--r-- | src/backend/replication/walreceiver.c | 20 | ||||
-rw-r--r-- | src/include/access/xlog_internal.h | 1 |
3 files changed, 79 insertions, 1 deletions
diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c index 52922dae4ec..0c178c55c87 100644 --- a/src/backend/access/transam/xlogarchive.c +++ b/src/backend/access/transam/xlogarchive.c @@ -474,6 +474,12 @@ KeepFileRestoredFromArchive(char *path, char *xlogfname) path, xlogfpath))); /* + * Create .done file forcibly to prevent the restored segment from + * being archived again later. + */ + XLogArchiveForceDone(xlogfname); + + /* * If the existing file was replaced, since walsenders might have it * open, request them to reload a currently-open segment. This is only * required for WAL segments, walsenders don't hold other files open, but @@ -545,6 +551,59 @@ XLogArchiveNotifySeg(XLogSegNo segno) } /* + * XLogArchiveForceDone + * + * Emit notification forcibly that an XLOG segment file has been successfully + * archived, by creating <XLOG>.done regardless of whether <XLOG>.ready + * exists or not. + */ +void +XLogArchiveForceDone(const char *xlog) +{ + char archiveReady[MAXPGPATH]; + char archiveDone[MAXPGPATH]; + struct stat stat_buf; + FILE *fd; + + /* Exit if already known done */ + StatusFilePath(archiveDone, xlog, ".done"); + if (stat(archiveDone, &stat_buf) == 0) + return; + + /* If .ready exists, rename it to .done */ + StatusFilePath(archiveReady, xlog, ".ready"); + if (stat(archiveReady, &stat_buf) == 0) + { + if (rename(archiveReady, archiveDone) < 0) + ereport(WARNING, + (errcode_for_file_access(), + errmsg("could not rename file \"%s\" to \"%s\": %m", + archiveReady, archiveDone))); + + return; + } + + /* insert an otherwise empty file called <XLOG>.done */ + fd = AllocateFile(archiveDone, "w"); + if (fd == NULL) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not create archive status file \"%s\": %m", + archiveDone))); + return; + } + if (FreeFile(fd)) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not write archive status file \"%s\": %m", + archiveDone))); + return; + } +} + +/* * XLogArchiveCheckDone * * This is called when we are ready to delete or recycle an old XLOG segment diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 37d5e0821ed..911a66ba887 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -83,7 +83,7 @@ walrcv_disconnect_type walrcv_disconnect = NULL; /* * These variables are used similarly to openLogFile/SegNo/Off, * but for walreceiver to write the XLOG. recvFileTLI is the TimeLineID - * corresponding the filename of recvFile, used for error messages. + * corresponding the filename of recvFile. */ static int recvFile = -1; static TimeLineID recvFileTLI = 0; @@ -528,12 +528,21 @@ WalReceiverMain(void) */ if (recvFile >= 0) { + char xlogfname[MAXFNAMELEN]; + XLogWalRcvFlush(false); if (close(recvFile) != 0) ereport(PANIC, (errcode_for_file_access(), errmsg("could not close log segment %s: %m", XLogFileNameP(recvFileTLI, recvSegNo)))); + + /* + * Create .done file forcibly to prevent the streamed segment from + * being archived later. + */ + XLogFileName(xlogfname, recvFileTLI, recvSegNo); + XLogArchiveForceDone(xlogfname); } recvFile = -1; @@ -865,6 +874,8 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) */ if (recvFile >= 0) { + char xlogfname[MAXFNAMELEN]; + XLogWalRcvFlush(false); /* @@ -877,6 +888,13 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) (errcode_for_file_access(), errmsg("could not close log segment %s: %m", XLogFileNameP(recvFileTLI, recvSegNo)))); + + /* + * Create .done file forcibly to prevent the streamed segment from + * being archived later. + */ + XLogFileName(xlogfname, recvFileTLI, recvSegNo); + XLogArchiveForceDone(xlogfname); } recvFile = -1; diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 16b53e37260..c996c3c3ad8 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -278,6 +278,7 @@ extern void ExecuteRecoveryCommand(char *command, char *commandName, extern void KeepFileRestoredFromArchive(char *path, char *xlogfname); extern void XLogArchiveNotify(const char *xlog); extern void XLogArchiveNotifySeg(XLogSegNo segno); +extern void XLogArchiveForceDone(const char *xlog); extern bool XLogArchiveCheckDone(const char *xlog); extern bool XLogArchiveIsBusy(const char *xlog); extern void XLogArchiveCleanup(const char *xlog); |