Skip to content

Commit c2f79ba

Browse files
simonat2ndQuadranthlinnaka
authored andcommitted
Force archive_status of .done for xlogs created by dearchival/replication.
This is a forward-patch of commit 6f4b8a4, applied to 9.2 back in August. The plan was to do something else in master, but it looks like it's not going to happen, so let's just apply the 9.2 solution to master as well. Fujii Masao
1 parent c9cc7e0 commit c2f79ba

File tree

3 files changed

+79
-1
lines changed

3 files changed

+79
-1
lines changed

src/backend/access/transam/xlogarchive.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,12 @@ KeepFileRestoredFromArchive(char *path, char *xlogfname)
473473
errmsg("could not rename file \"%s\" to \"%s\": %m",
474474
path, xlogfpath)));
475475

476+
/*
477+
* Create .done file forcibly to prevent the restored segment from
478+
* being archived again later.
479+
*/
480+
XLogArchiveForceDone(xlogfname);
481+
476482
/*
477483
* If the existing file was replaced, since walsenders might have it
478484
* open, request them to reload a currently-open segment. This is only
@@ -544,6 +550,59 @@ XLogArchiveNotifySeg(XLogSegNo segno)
544550
XLogArchiveNotify(xlog);
545551
}
546552

553+
/*
554+
* XLogArchiveForceDone
555+
*
556+
* Emit notification forcibly that an XLOG segment file has been successfully
557+
* archived, by creating <XLOG>.done regardless of whether <XLOG>.ready
558+
* exists or not.
559+
*/
560+
void
561+
XLogArchiveForceDone(const char *xlog)
562+
{
563+
char archiveReady[MAXPGPATH];
564+
char archiveDone[MAXPGPATH];
565+
struct stat stat_buf;
566+
FILE *fd;
567+
568+
/* Exit if already known done */
569+
StatusFilePath(archiveDone, xlog, ".done");
570+
if (stat(archiveDone, &stat_buf) == 0)
571+
return;
572+
573+
/* If .ready exists, rename it to .done */
574+
StatusFilePath(archiveReady, xlog, ".ready");
575+
if (stat(archiveReady, &stat_buf) == 0)
576+
{
577+
if (rename(archiveReady, archiveDone) < 0)
578+
ereport(WARNING,
579+
(errcode_for_file_access(),
580+
errmsg("could not rename file \"%s\" to \"%s\": %m",
581+
archiveReady, archiveDone)));
582+
583+
return;
584+
}
585+
586+
/* insert an otherwise empty file called <XLOG>.done */
587+
fd = AllocateFile(archiveDone, "w");
588+
if (fd == NULL)
589+
{
590+
ereport(LOG,
591+
(errcode_for_file_access(),
592+
errmsg("could not create archive status file \"%s\": %m",
593+
archiveDone)));
594+
return;
595+
}
596+
if (FreeFile(fd))
597+
{
598+
ereport(LOG,
599+
(errcode_for_file_access(),
600+
errmsg("could not write archive status file \"%s\": %m",
601+
archiveDone)));
602+
return;
603+
}
604+
}
605+
547606
/*
548607
* XLogArchiveCheckDone
549608
*

src/backend/replication/walreceiver.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ walrcv_disconnect_type walrcv_disconnect = NULL;
8383
/*
8484
* These variables are used similarly to openLogFile/SegNo/Off,
8585
* but for walreceiver to write the XLOG. recvFileTLI is the TimeLineID
86-
* corresponding the filename of recvFile, used for error messages.
86+
* corresponding the filename of recvFile.
8787
*/
8888
static int recvFile = -1;
8989
static TimeLineID recvFileTLI = 0;
@@ -528,12 +528,21 @@ WalReceiverMain(void)
528528
*/
529529
if (recvFile >= 0)
530530
{
531+
char xlogfname[MAXFNAMELEN];
532+
531533
XLogWalRcvFlush(false);
532534
if (close(recvFile) != 0)
533535
ereport(PANIC,
534536
(errcode_for_file_access(),
535537
errmsg("could not close log segment %s: %m",
536538
XLogFileNameP(recvFileTLI, recvSegNo))));
539+
540+
/*
541+
* Create .done file forcibly to prevent the streamed segment from
542+
* being archived later.
543+
*/
544+
XLogFileName(xlogfname, recvFileTLI, recvSegNo);
545+
XLogArchiveForceDone(xlogfname);
537546
}
538547
recvFile = -1;
539548

@@ -865,6 +874,8 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
865874
*/
866875
if (recvFile >= 0)
867876
{
877+
char xlogfname[MAXFNAMELEN];
878+
868879
XLogWalRcvFlush(false);
869880

870881
/*
@@ -877,6 +888,13 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
877888
(errcode_for_file_access(),
878889
errmsg("could not close log segment %s: %m",
879890
XLogFileNameP(recvFileTLI, recvSegNo))));
891+
892+
/*
893+
* Create .done file forcibly to prevent the streamed segment from
894+
* being archived later.
895+
*/
896+
XLogFileName(xlogfname, recvFileTLI, recvSegNo);
897+
XLogArchiveForceDone(xlogfname);
880898
}
881899
recvFile = -1;
882900

src/include/access/xlog_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ extern void ExecuteRecoveryCommand(char *command, char *commandName,
278278
extern void KeepFileRestoredFromArchive(char *path, char *xlogfname);
279279
extern void XLogArchiveNotify(const char *xlog);
280280
extern void XLogArchiveNotifySeg(XLogSegNo segno);
281+
extern void XLogArchiveForceDone(const char *xlog);
281282
extern bool XLogArchiveCheckDone(const char *xlog);
282283
extern bool XLogArchiveIsBusy(const char *xlog);
283284
extern void XLogArchiveCleanup(const char *xlog);

0 commit comments

Comments
 (0)