From 76b81eeacae1887883cfb4df45671dd8cdc3a41c Mon Sep 17 00:00:00 2001 From: Konstantin Knizhnik Date: Fri, 4 Apr 2025 14:31:45 +0300 Subject: [PATCH 1/2] Move CheckPointBuffers to PreCheckPointGuts to save FSM/VM pages on normal shutdown --- src/backend/access/transam/xlog.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 86287161a21..b1cf28a8874 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7679,6 +7679,7 @@ PreCheckPointGuts(int flags) if (flags & CHECKPOINT_IS_SHUTDOWN) { CheckPointReplicationState(flags); + CheckPointBuffers(flags); /* * pgstat_write_statsfile will be called later by before_shmem_exit() hook, but by then it's too late * to write WAL records. In Neon, pgstat_write_statsfile() writes the pgstats file to the WAL, so we have @@ -7708,7 +7709,8 @@ CheckPointGuts(XLogRecPtr checkPointRedo, int flags) CheckPointSUBTRANS(); CheckPointMultiXact(); CheckPointPredicate(); - CheckPointBuffers(flags); + if (!(flags & CHECKPOINT_IS_SHUTDOWN)) + CheckPointBuffers(flags); /* Perform all queued up fsyncs */ TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START(); From 66114c23bc61205b0e3fb1e77ee76a4abc1eb4b8 Mon Sep 17 00:00:00 2001 From: Konstantin Knizhnik Date: Fri, 4 Apr 2025 21:34:01 +0300 Subject: [PATCH 2/2] Add comment explaning why CheckPointBuffers has to be called in PreCheckPointGuts --- src/backend/access/transam/xlog.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index b1cf28a8874..b16fcf0086c 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7671,7 +7671,8 @@ CheckPointReplicationState(int flags) /* * NEON: we use logical records to persist information of about slots, origins, relation map... * If it is done inside shutdown checkpoint, then Postgres panics: "concurrent write-ahead log activity while database system is shutting down" - * So it before checkpoint REDO position is determined. + * So do it before checkpoint REDO position is determined. + * The same is true for CheckPointBuffers which wallog dirty FSM/VM pages. */ static void PreCheckPointGuts(int flags) @@ -7680,10 +7681,11 @@ PreCheckPointGuts(int flags) { CheckPointReplicationState(flags); CheckPointBuffers(flags); + /* * pgstat_write_statsfile will be called later by before_shmem_exit() hook, but by then it's too late * to write WAL records. In Neon, pgstat_write_statsfile() writes the pgstats file to the WAL, so we have - * to call it earlier. (The call that happens later is useless, but it doesn't do any harm either) + * to call it earlier. (The call that happens later is useless, but it doesn't do any harm either) */ pgstat_write_statsfile(); } @@ -7709,6 +7711,12 @@ CheckPointGuts(XLogRecPtr checkPointRedo, int flags) CheckPointSUBTRANS(); CheckPointMultiXact(); CheckPointPredicate(); + /* + * NEON: Checkpoint buffer will write dirty pages to the disk and Neon SMGR + * wallog FSM/VM pages to persist them at page server. + * Writing to the WAL during shutdown checkpoint cause Postgres panic. + * So do it before in PreCheckPointGuts. + */ if (!(flags & CHECKPOINT_IS_SHUTDOWN)) CheckPointBuffers(flags);