From 734b2475ece6150f827670d5ffbe44a6dba864b4 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 9 Feb 2009 11:52:19 +0200 Subject: [PATCH] If a restartpoint is in progress at end of recovery, hurry it. --- src/backend/access/transam/xlog.c | 21 ++++++++++++++++++++- src/backend/postmaster/bgwriter.c | 12 ++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index bcc54eb174..0ace629e8f 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6026,7 +6026,26 @@ CreateCheckPoint(int flags) /* * Acquire CheckpointLock to ensure only one checkpoint happens at a time. */ - LWLockAcquire(CheckpointLock, LW_EXCLUSIVE); + if (!LWLockConditionalAcquire(CheckpointLock, LW_EXCLUSIVE)) + { + /* + * This should only happen at the end of archive recovery. + * During normal operation, only bgwriter creates checkpoints. + */ + Assert(InRecovery); + + /* + * A restartpoint is in progress. Wait until it finishes. This can + * cause an extra restartpoint to be performed, but that's OK because + * we're just about to perform a checkpoint anyway. Flushing the + * buffers in this restartpoint can take some time, but that time is + * saved from the upcoming checkpoint so the net effect is zero. + */ + elog(DEBUG2, "hurrying in-progress restartpoint"); + RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT); + + LWLockAcquire(CheckpointLock, LW_EXCLUSIVE); + } /* * Prepare to accumulate statistics. diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index c1f29189ea..79aa36dc3a 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -499,12 +499,12 @@ BackgroundWriterMain(void) /* * Indicate checkpoint completion to any waiting backends. */ + SpinLockAcquire(&bgs->ckpt_lck); + bgs->ckpt_done = bgs->ckpt_started; + SpinLockRelease(&bgs->ckpt_lck); + if (ckpt_performed) { - SpinLockAcquire(&bgs->ckpt_lck); - bgs->ckpt_done = bgs->ckpt_started; - SpinLockRelease(&bgs->ckpt_lck); - /* * Note we record the checkpoint start time not end time as * last_checkpoint_time. This is so that time-driven @@ -517,10 +517,10 @@ BackgroundWriterMain(void) /* * We were not able to perform the restartpoint (checkpoints * throw an ERROR in case of error). Most likely because we - * have not received a new checkpoint WAL record since the + * have not received any new checkpoint WAL records since the * last restartpoint. Try again in 15 s. */ - last_checkpoint_time = now - CheckPointTimeout - 15; + last_checkpoint_time = now - CheckPointTimeout + 15; } ckpt_active = false; -- 2.30.2