aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlogarchive.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xlogarchive.c')
-rw-r--r--src/backend/access/transam/xlogarchive.c59
1 files changed, 59 insertions, 0 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