Improve the checkpoint signaling mechanism so that the bgwriter can tell

the difference between checkpoints forced due to WAL segment consumption
and checkpoints forced for other reasons (such as CREATE DATABASE).  Avoid
generating 'checkpoints are occurring too frequently' messages when the
checkpoint wasn't caused by WAL segment consumption.  Per gripe from
Chris K-L.
This commit is contained in:
Tom Lane 2005-06-30 00:00:52 +00:00
parent b5f7cff84f
commit 401de9c8be
6 changed files with 45 additions and 29 deletions

View File

@ -24,7 +24,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.30 2005/06/06 20:22:57 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/clog.c,v 1.31 2005/06/30 00:00:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -336,7 +336,7 @@ TruncateCLOG(TransactionId oldestXact)
return; /* nothing to remove */ return; /* nothing to remove */
/* Perform a CHECKPOINT */ /* Perform a CHECKPOINT */
RequestCheckpoint(true); RequestCheckpoint(true, false);
/* Now we can remove the old CLOG segment(s) */ /* Now we can remove the old CLOG segment(s) */
SimpleLruTruncate(ClogCtl, cutoffPage); SimpleLruTruncate(ClogCtl, cutoffPage);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.204 2005/06/29 22:51:53 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.205 2005/06/30 00:00:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1337,7 +1337,7 @@ XLogWrite(XLogwrtRqst WriteRqst)
if (XLOG_DEBUG) if (XLOG_DEBUG)
elog(LOG, "time for a checkpoint, signaling bgwriter"); elog(LOG, "time for a checkpoint, signaling bgwriter");
#endif #endif
RequestCheckpoint(false); RequestCheckpoint(false, true);
} }
} }
} }
@ -5496,7 +5496,7 @@ pg_start_backup(PG_FUNCTION_ARGS)
* will have different checkpoint positions and hence different * will have different checkpoint positions and hence different
* history file names, even if nothing happened in between. * history file names, even if nothing happened in between.
*/ */
RequestCheckpoint(true); RequestCheckpoint(true, false);
/* /*
* Now we need to fetch the checkpoint record location, and also its * Now we need to fetch the checkpoint record location, and also its

View File

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.163 2005/06/29 20:34:13 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.164 2005/06/30 00:00:50 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -542,7 +542,7 @@ createdb(const CreatedbStmt *stmt)
* Perhaps if we ever implement CREATE DATABASE in a less cheesy * Perhaps if we ever implement CREATE DATABASE in a less cheesy
* way, we can avoid this. * way, we can avoid this.
*/ */
RequestCheckpoint(true); RequestCheckpoint(true, false);
/* /*
* Set flag to update flat database file at commit. * Set flag to update flat database file at commit.
@ -668,7 +668,7 @@ dropdb(const char *dbname)
* open files, which would cause rmdir() to fail. * open files, which would cause rmdir() to fail.
*/ */
#ifdef WIN32 #ifdef WIN32
RequestCheckpoint(true); RequestCheckpoint(true, false);
#endif #endif
/* /*

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.16 2005/05/28 17:21:32 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.17 2005/06/30 00:00:51 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -86,8 +86,14 @@
* 6. If ckpt_failed is different from the originally saved value, * 6. If ckpt_failed is different from the originally saved value,
* assume request failed; otherwise it was definitely successful. * assume request failed; otherwise it was definitely successful.
* *
* An additional field is ckpt_time_warn; this is also sig_atomic_t for
* simplicity, but is only used as a boolean. If a backend is requesting
* a checkpoint for which a checkpoints-too-close-together warning is
* reasonable, it should set this field TRUE just before sending the signal.
*
* The requests array holds fsync requests sent by backends and not yet * The requests array holds fsync requests sent by backends and not yet
* absorbed by the bgwriter. * absorbed by the bgwriter. Unlike the checkpoint fields, the requests
* fields are protected by BgWriterCommLock.
*---------- *----------
*/ */
typedef struct typedef struct
@ -105,6 +111,8 @@ typedef struct
sig_atomic_t ckpt_done; /* advances when checkpoint done */ sig_atomic_t ckpt_done; /* advances when checkpoint done */
sig_atomic_t ckpt_failed; /* advances when checkpoint fails */ sig_atomic_t ckpt_failed; /* advances when checkpoint fails */
sig_atomic_t ckpt_time_warn; /* warn if too soon since last ckpt? */
int num_requests; /* current # of requests */ int num_requests; /* current # of requests */
int max_requests; /* allocated array size */ int max_requests; /* allocated array size */
BgWriterRequest requests[1]; /* VARIABLE LENGTH ARRAY */ BgWriterRequest requests[1]; /* VARIABLE LENGTH ARRAY */
@ -319,20 +327,20 @@ BackgroundWriterMain(void)
*/ */
if (do_checkpoint) if (do_checkpoint)
{ {
if (CheckPointWarning != 0) /*
{ * We will warn if (a) too soon since last checkpoint (whatever
/* * caused it) and (b) somebody has set the ckpt_time_warn flag
* Ideally we should only warn if this checkpoint was * since the last checkpoint start. Note in particular that
* requested due to running out of segment files, and not * this implementation will not generate warnings caused by
* if it was manually requested. However we can't tell * CheckPointTimeout < CheckPointWarning.
* the difference with the current signalling mechanism. */
*/ if (BgWriterShmem->ckpt_time_warn &&
if (elapsed_secs < CheckPointWarning) elapsed_secs < CheckPointWarning)
ereport(LOG, ereport(LOG,
(errmsg("checkpoints are occurring too frequently (%d seconds apart)", (errmsg("checkpoints are occurring too frequently (%d seconds apart)",
elapsed_secs), elapsed_secs),
errhint("Consider increasing the configuration parameter \"checkpoint_segments\"."))); errhint("Consider increasing the configuration parameter \"checkpoint_segments\".")));
} BgWriterShmem->ckpt_time_warn = false;
/* /*
* Indicate checkpoint start to any waiting backends. * Indicate checkpoint start to any waiting backends.
@ -497,9 +505,13 @@ BgWriterShmemInit(void)
* If waitforit is true, wait until the checkpoint is completed * If waitforit is true, wait until the checkpoint is completed
* before returning; otherwise, just signal the request and return * before returning; otherwise, just signal the request and return
* immediately. * immediately.
*
* If warnontime is true, and it's "too soon" since the last checkpoint,
* the bgwriter will log a warning. This should be true only for checkpoints
* caused due to xlog filling, else the warning will be misleading.
*/ */
void void
RequestCheckpoint(bool waitforit) RequestCheckpoint(bool waitforit, bool warnontime)
{ {
/* use volatile pointer to prevent code rearrangement */ /* use volatile pointer to prevent code rearrangement */
volatile BgWriterShmemStruct *bgs = BgWriterShmem; volatile BgWriterShmemStruct *bgs = BgWriterShmem;
@ -523,6 +535,10 @@ RequestCheckpoint(bool waitforit)
return; return;
} }
/* Set warning request flag if appropriate */
if (warnontime)
bgs->ckpt_time_warn = true;
/* /*
* Send signal to request checkpoint. When waitforit is false, we * Send signal to request checkpoint. When waitforit is false, we
* consider failure to send the signal to be nonfatal. * consider failure to send the signal to be nonfatal.

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.239 2005/06/28 05:09:00 tgl Exp $ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.240 2005/06/30 00:00:51 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -989,7 +989,7 @@ ProcessUtility(Node *parsetree,
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to do CHECKPOINT"))); errmsg("must be superuser to do CHECKPOINT")));
RequestCheckpoint(true); RequestCheckpoint(true, false);
break; break;
case T_ReindexStmt: case T_ReindexStmt:

View File

@ -5,7 +5,7 @@
* *
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/postmaster/bgwriter.h,v 1.5 2005/03/04 20:21:06 tgl Exp $ * $PostgreSQL: pgsql/src/include/postmaster/bgwriter.h,v 1.6 2005/06/30 00:00:52 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -23,7 +23,7 @@ extern int CheckPointWarning;
extern void BackgroundWriterMain(void); extern void BackgroundWriterMain(void);
extern void RequestCheckpoint(bool waitforit); extern void RequestCheckpoint(bool waitforit, bool warnontime);
extern bool ForwardFsyncRequest(RelFileNode rnode, BlockNumber segno); extern bool ForwardFsyncRequest(RelFileNode rnode, BlockNumber segno);
extern void AbsorbFsyncRequests(void); extern void AbsorbFsyncRequests(void);