From 3d97d3aaafb4a6e7ea8d283e858c0200b6a2a1cc Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sun, 20 Feb 2022 12:17:03 -0800
Subject: [PATCH v1 4/5] initdb: Optimize WAL writing during initdb.

Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
 src/include/miscadmin.h                 |  3 +++
 src/backend/access/transam/xloginsert.c | 18 ++++++++++++------
 src/backend/bootstrap/bootstrap.c       |  2 +-
 src/backend/catalog/heap.c              |  4 +++-
 src/backend/commands/dbcommands.c       | 16 +++++++++++++---
 5 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 0abc3ad5405..9af1f46b3b2 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -396,6 +396,7 @@ extern bool superuser_arg(Oid roleid);	/* given user is superuser */
 typedef enum ProcessingMode
 {
 	BootstrapProcessing,		/* bootstrap creation of template database */
+	LateBootstrapProcessing,	/* XXX bootstrap initializing more stuff */
 	InitProcessing,				/* initializing system */
 	NormalProcessing			/* normal processing */
 } ProcessingMode;
@@ -403,6 +404,7 @@ typedef enum ProcessingMode
 extern ProcessingMode Mode;
 
 #define IsBootstrapProcessingMode() (Mode == BootstrapProcessing)
+#define IsLateBootstrapProcessingMode() (Mode == LateBootstrapProcessing)
 #define IsInitProcessingMode()		(Mode == InitProcessing)
 #define IsNormalProcessingMode()	(Mode == NormalProcessing)
 
@@ -411,6 +413,7 @@ extern ProcessingMode Mode;
 #define SetProcessingMode(mode) \
 	do { \
 		AssertArg((mode) == BootstrapProcessing || \
+				  (mode) == LateBootstrapProcessing || \
 				  (mode) == InitProcessing || \
 				  (mode) == NormalProcessing); \
 		Mode = (mode); \
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index c260310c4c8..cd4316b108e 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -446,14 +446,20 @@ XLogInsert(RmgrId rmid, uint8 info)
 	TRACE_POSTGRESQL_WAL_INSERT(rmid, info);
 
 	/*
-	 * In bootstrap mode, we don't actually log anything but XLOG resources;
-	 * return a phony record pointer.
+	 * In bootstrap mode, we don't actually log anything but shutdown
+	 * checkpoint records; return a phony record pointer.
 	 */
-	if (IsBootstrapProcessingMode() && rmid != RM_XLOG_ID)
+	if (IsBootstrapProcessingMode() || IsLateBootstrapProcessingMode())
 	{
-		XLogResetInsertion();
-		EndPos = SizeOfXLogLongPHD; /* start of 1st chkpt record */
-		return EndPos;
+		uint8		rectype = info & ~XLR_INFO_MASK;
+
+		if (rmid != RM_XLOG_ID ||
+			rectype != XLOG_CHECKPOINT_SHUTDOWN)
+		{
+			XLogResetInsertion();
+			EndPos = SizeOfXLogLongPHD; /* start of 1st chkpt record */
+			return EndPos;
+		}
 	}
 
 	do
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 3fd8ed60715..6230ba17685 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -451,7 +451,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
 	/*
 	 * Load further catalog contents by running a bunch of SQL commands.
 	 */
-	SetProcessingMode(NormalProcessing);
+	SetProcessingMode(LateBootstrapProcessing);
 
 	bootstrap_load_nonbki(share_path);
 
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 7e99de88b34..486f0e5ea1f 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -1138,7 +1138,9 @@ heap_create_with_catalog(const char *relname,
 	/*
 	 * sanity checks
 	 */
-	Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());
+	Assert(IsNormalProcessingMode() ||
+		   IsBootstrapProcessingMode() ||
+		   IsLateBootstrapProcessingMode());
 
 	/*
 	 * Validate proposed tupdesc for the desired relkind.  If
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index c37e3c9a9a4..1720bad1d07 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -676,9 +676,15 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 	 * happened while we're copying files, a file might be deleted just when
 	 * we're about to copy it, causing the lstat() call in copydir() to fail
 	 * with ENOENT.
+	 *
+	 * In bootstrap mode FlushDatabaseBuffers() suffices because there are
+	 * unlink requests.
 	 */
-	RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT
-					  | CHECKPOINT_FLUSH_ALL);
+	if (IsBootstrapProcessingMode() || IsLateBootstrapProcessingMode())
+		FlushDatabaseBuffers(src_dboid);
+	else
+		RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT
+						  | CHECKPOINT_FLUSH_ALL);
 
 	/*
 	 * Once we start copying subdirectories, we need to be able to clean 'em
@@ -782,8 +788,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 		 *
 		 * Perhaps if we ever implement CREATE DATABASE in a less cheesy way,
 		 * we can avoid this.
+		 *
+		 * We do not need this checkpoint in bootstrap mode - if we fail, the
+		 * cluster won't be valid anyway.
 		 */
-		RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT);
+		if (!IsBootstrapProcessingMode() && !IsLateBootstrapProcessingMode())
+			RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_FORCE | CHECKPOINT_WAIT);
 
 		/*
 		 * Close pg_database, but keep lock till commit.
-- 
2.34.0

