summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-11-23 01:40:19 +0000
committerTom Lane2008-11-23 01:40:19 +0000
commit6b66d7ee8b890e51feba79a51997b8929786b59b (patch)
tree8396c6921028960e39b7a5ecb013997c846ff140
parent10082916d06f701b8e73c33cba2cdb5e98b72fed (diff)
Teach RequestCheckpoint() to wait and retry a few times if it can't signal
the bgwriter immediately. This covers the case where the bgwriter is still starting up, as seen in a recent buildfarm failure. In future it might also assist with clean recovery after a bgwriter termination and restart --- right now the postmaster treats early bgwriter exit as a system crash, but that might not always be so.
-rw-r--r--src/backend/postmaster/bgwriter.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 2ddd0c7d33..72188d994a 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -864,6 +864,7 @@ RequestCheckpoint(int flags)
{
/* use volatile pointer to prevent code rearrangement */
volatile BgWriterShmemStruct *bgs = BgWriterShmem;
+ int ntries;
int old_failed,
old_started;
@@ -905,15 +906,38 @@ RequestCheckpoint(int flags)
SpinLockRelease(&bgs->ckpt_lck);
/*
- * Send signal to request checkpoint. When not waiting, we consider
- * failure to send the signal to be nonfatal.
+ * Send signal to request checkpoint. It's possible that the bgwriter
+ * hasn't started yet, or is in process of restarting, so we will retry
+ * a few times if needed. Also, if not told to wait for the checkpoint
+ * to occur, we consider failure to send the signal to be nonfatal and
+ * merely LOG it.
*/
- if (BgWriterShmem->bgwriter_pid == 0)
- elog((flags & CHECKPOINT_WAIT) ? ERROR : LOG,
- "could not request checkpoint because bgwriter not running");
- if (kill(BgWriterShmem->bgwriter_pid, SIGINT) != 0)
- elog((flags & CHECKPOINT_WAIT) ? ERROR : LOG,
- "could not signal for checkpoint: %m");
+ for (ntries = 0; ; ntries++)
+ {
+ if (BgWriterShmem->bgwriter_pid == 0)
+ {
+ if (ntries >= 20) /* max wait 2.0 sec */
+ {
+ elog((flags & CHECKPOINT_WAIT) ? ERROR : LOG,
+ "could not request checkpoint because bgwriter not running");
+ break;
+ }
+ }
+ else if (kill(BgWriterShmem->bgwriter_pid, SIGINT) != 0)
+ {
+ if (ntries >= 20) /* max wait 2.0 sec */
+ {
+ elog((flags & CHECKPOINT_WAIT) ? ERROR : LOG,
+ "could not signal for checkpoint: %m");
+ break;
+ }
+ }
+ else
+ break; /* signal sent successfully */
+
+ CHECK_FOR_INTERRUPTS();
+ pg_usleep(100000L); /* wait 0.1 sec, then retry */
+ }
/*
* If requested, wait for completion. We detect completion according to