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