From 77ec7a6a192e227899c80a873c4479c866024587 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 19 Mar 2021 13:06:35 +1300
Subject: [PATCH v6 2/3] Provide recovery_init_sync_method=none.

Although it's rife with hazards and not a good option to use in general,
some expert users may want to be able to disable the initial sync
performed before crash recovery.  Explicitly discouraged in the
documentation.

Discussion https://postgr.es/m/11bc2bb7-ecb5-3ad0-b39f-df632734cd81%40discourse.org
---
 doc/src/sgml/config.sgml                      | 9 +++++++++
 src/backend/storage/file/fd.c                 | 9 +++++++--
 src/backend/utils/misc/guc.c                  | 1 +
 src/backend/utils/misc/postgresql.conf.sample | 2 +-
 src/include/storage/fd.h                      | 3 ++-
 5 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 32de8235bf..0d058de261 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -9748,6 +9748,15 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
         <productname>PostgreSQL</productname>, and relevant error messages may
         appear only in kernel logs.
        </para>
+       <para>
+        The option <literal>none</literal> can be specified to skip this step.
+        This is only safe if all buffered data is known to have been flushed
+        to disk already, for example by a tool such as
+        <application>pg_basebackup</application> without
+        <literal>--no-sync</literal>.  It is not a good idea to
+        leave this option configured permanently in general, as it will
+        affect future crash recovery cycles.
+       </para>
       </listitem>
      </varlistentry>
 
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 28933f8bbe..b59fbc4cfe 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -3293,8 +3293,9 @@ do_syncfs(const char *path)
 #endif
 
 /*
- * Issue fsync recursively on PGDATA and all its contents, or issue syncfs for
- * all potential filesystem, depending on recovery_init_sync_method setting.
+ * Issue fsync recursively on PGDATA and all its contents, issue syncfs for all
+ * potential filesystem, or do nothing, depending on the
+ * recovery_init_sync_method setting.
  *
  * We fsync regular files and directories wherever they are, but we
  * follow symlinks only for pg_wal and immediately under pg_tblspc.
@@ -3323,6 +3324,10 @@ SyncDataDirectory(void)
 	if (!enableFsync)
 		return;
 
+	/* Likewise if this specific sync step is disabled. */
+	if (recovery_init_sync_method == RECOVERY_INIT_SYNC_METHOD_NONE)
+		return;
+
 	/*
 	 * If pg_wal is a symlink, we'll need to recurse into it separately,
 	 * because the first walkdir below will ignore it.
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8679063e5f..4fa67a5160 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -492,6 +492,7 @@ static struct config_enum_entry recovery_init_sync_method_options[] = {
 #ifdef HAVE_SYNCFS
 	{"syncfs", RECOVERY_INIT_SYNC_METHOD_SYNCFS, false},
 #endif
+	{"none", RECOVERY_INIT_SYNC_METHOD_NONE, false},
 	{NULL, 0, false}
 };
 
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 76b9e815a2..8b1610f6ec 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -760,7 +760,7 @@
 #restart_after_crash = on		# reinitialize after backend crash?
 #remove_temp_files_after_crash = on	# remove temporary files after
 					# backend crash?
-#recovery_init_sync_method = fsync	# fsync, syncfs (Linux 5.8+)
+#recovery_init_sync_method = fsync	# fsync, syncfs (Linux 5.8+), none
 #data_sync_retry = off			# retry or panic on failure to fsync
 					# data?
 					# (change requires restart)
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 328473bdc9..dca44c38c4 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -47,7 +47,8 @@
 
 typedef enum RecoveryInitSyncMethod {
 	RECOVERY_INIT_SYNC_METHOD_FSYNC,
-	RECOVERY_INIT_SYNC_METHOD_SYNCFS
+	RECOVERY_INIT_SYNC_METHOD_SYNCFS,
+	RECOVERY_INIT_SYNC_METHOD_NONE
 } RecoveryInitSyncMethod;
 
 struct iovec;					/* avoid including port/pg_iovec.h here */
-- 
2.30.1

