From a6d033aff90a6218345cba41847ccfdfbe6447d7 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandbossart@gmail.com>
Date: Mon, 21 Feb 2022 16:29:14 -0800
Subject: [PATCH v1 1/1] remove more archiving overhead

---
 src/backend/access/transam/xlogarchive.c | 15 +++++++++++++--
 src/backend/postmaster/pgarch.c          | 13 ++++++++++++-
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c
index a2657a2005..d6823c9c38 100644
--- a/src/backend/access/transam/xlogarchive.c
+++ b/src/backend/access/transam/xlogarchive.c
@@ -585,8 +585,13 @@ XLogArchiveForceDone(const char *xlog)
  * If it is not time to delete it, make sure a .ready file exists, and return
  * false.
  *
- * If <XLOG>.done exists, then return true; else if <XLOG>.ready exists,
- * then return false; else create <XLOG>.ready and return false.
+ * If <XLOG>.done exists, then sync the archive_status directory to disk and
+ * return true.  Syncing the directory ensures that the rename from
+ * <XLOG>.ready to <XLOG>.done is persisted so that we won't attempt to re-
+ * archive the file after a crash.
+ *
+ * If <XLOG>.ready exists, then return false.  If neither <XLOG>.ready nor
+ * <XLOG>.done exist, create <XLOG>.ready and return false.
  *
  * The reason we do things this way is so that if the original attempt to
  * create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
@@ -618,7 +623,10 @@ XLogArchiveCheckDone(const char *xlog)
 	/* First check for .done --- this means archiver is done with it */
 	StatusFilePath(archiveStatusPath, xlog, ".done");
 	if (stat(archiveStatusPath, &stat_buf) == 0)
+	{
+		fsync_fname(XLOGDIR "/archive_status", true);
 		return true;
+	}
 
 	/* check for .ready --- this means archiver is still busy with it */
 	StatusFilePath(archiveStatusPath, xlog, ".ready");
@@ -628,7 +636,10 @@ XLogArchiveCheckDone(const char *xlog)
 	/* Race condition --- maybe archiver just finished, so recheck */
 	StatusFilePath(archiveStatusPath, xlog, ".done");
 	if (stat(archiveStatusPath, &stat_buf) == 0)
+	{
+		fsync_fname(XLOGDIR "/archive_status", true);
 		return true;
+	}
 
 	/* Retry creation of the .ready file */
 	XLogArchiveNotify(xlog);
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index d916ed39a8..44cb58e1f4 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -746,7 +746,18 @@ pgarch_archiveDone(char *xlog)
 
 	StatusFilePath(rlogready, xlog, ".ready");
 	StatusFilePath(rlogdone, xlog, ".done");
-	(void) durable_rename(rlogready, rlogdone, WARNING);
+
+	/*
+	 * To reduce overhead, we don't durably rename the .ready file to .done
+	 * here.  Whoever recycles or removes the WAL file is responsible for first
+	 * persisting the archive_status directory to disk so that we won't attempt
+	 * to re-archive the file after a crash.
+	 */
+	if (rename(rlogready, rlogdone) < 0)
+		ereport(WARNING,
+				(errcode_for_file_access(),
+				 errmsg("could not rename file \"%s\" to \"%s\": %m",
+						rlogready, rlogdone)));
 }
 
 
-- 
2.25.1

