The LogCheckpointStart() call inside CreateCheckPoint() is done while
inside a critical section. The elog call could trigger errors due to
memory allocations or from a logging hook, resulting in a panic. It
seems better to postpone the logging until after the critical section
is done. It's only a few lwlock acquisitions away and shouldn't make
any material difference. Patch to do so is attached.

Regards,
Ants Aasma
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 7375a78ffc..faa9690e48 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8907,15 +8907,6 @@ CreateCheckPoint(int flags)
 	XLogCtl->RedoRecPtr = checkPoint.redo;
 	SpinLockRelease(&XLogCtl->info_lck);
 
-	/*
-	 * If enabled, log checkpoint start.  We postpone this until now so as not
-	 * to log anything if we decided to skip the checkpoint.
-	 */
-	if (log_checkpoints)
-		LogCheckpointStart(flags, false);
-
-	TRACE_POSTGRESQL_CHECKPOINT_START(flags);
-
 	/*
 	 * Get the other info we need for the checkpoint record.
 	 *
@@ -8962,6 +8953,15 @@ CreateCheckPoint(int flags)
 	 */
 	END_CRIT_SECTION();
 
+	/*
+	 * If enabled, log checkpoint start.  We postpone this until now so as not
+	 * to log anything if we decided to skip the checkpoint.
+	 */
+	if (log_checkpoints)
+		LogCheckpointStart(flags, false);
+
+	TRACE_POSTGRESQL_CHECKPOINT_START(flags);
+
 	/*
 	 * In some cases there are groups of actions that must all occur on one
 	 * side or the other of a checkpoint record. Before flushing the

Reply via email to