summaryrefslogtreecommitdiff
path: root/src/backend/postmaster
diff options
context:
space:
mode:
authorMagnus Hagander2007-03-30 18:34:56 +0000
committerMagnus Hagander2007-03-30 18:34:56 +0000
commit335feca441b338f796e205f0e227b2f3a43f130e (patch)
tree9b11d242f2d60e4e38c87cb74946f04889de49bf /src/backend/postmaster
parentf9ce21f94cd90ffa5e6c63c91e8b05aa0b6d2b25 (diff)
Add some instrumentation to the bgwriter, through the stats collector.
New view pg_stat_bgwriter, and the functions required to build it.
Diffstat (limited to 'src/backend/postmaster')
-rw-r--r--src/backend/postmaster/bgwriter.c25
-rw-r--r--src/backend/postmaster/pgstat.c111
2 files changed, 134 insertions, 2 deletions
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 1224f556e83..273588424eb 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.36 2007/01/17 16:25:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.37 2007/03/30 18:34:55 mha Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,6 +50,7 @@
#include "access/xlog_internal.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
+#include "pgstat.h"
#include "postmaster/bgwriter.h"
#include "storage/fd.h"
#include "storage/freespace.h"
@@ -125,6 +126,13 @@ typedef struct
static BgWriterShmemStruct *BgWriterShmem;
/*
+ * BgWriter statistics counters.
+ * Stored directly in a stats message structure so it can be sent
+ * without needing to copy things around.
+ */
+PgStat_MsgBgWriter BgWriterStats;
+
+/*
* GUC parameters
*/
int BgWriterDelay = 200;
@@ -243,6 +251,11 @@ BackgroundWriterMain(void)
MemoryContextSwitchTo(bgwriter_context);
/*
+ * Initialize statistics counters to zero
+ */
+ memset(&BgWriterStats, 0, sizeof(BgWriterStats));
+
+ /*
* If an exception is encountered, processing resumes here.
*
* See notes in postgres.c about the design of this coding.
@@ -354,6 +367,7 @@ BackgroundWriterMain(void)
checkpoint_requested = false;
do_checkpoint = true;
force_checkpoint = true;
+ BgWriterStats.m_requested_checkpoints++;
}
if (shutdown_requested)
{
@@ -376,7 +390,11 @@ BackgroundWriterMain(void)
now = time(NULL);
elapsed_secs = now - last_checkpoint_time;
if (elapsed_secs >= CheckPointTimeout)
+ {
do_checkpoint = true;
+ if (!force_checkpoint)
+ BgWriterStats.m_timed_checkpoints++;
+ }
/*
* Do a checkpoint if requested, otherwise do one cycle of
@@ -474,6 +492,11 @@ BackgroundWriterMain(void)
}
/*
+ * Send off activity statistics to the stats collector
+ */
+ pgstat_send_bgwriter();
+
+ /*
* Nap for the configured time, or sleep for 10 seconds if there is no
* bgwriter activity configured.
*
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index fd19d5741c2..e1699cd0bdf 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.151 2007/03/28 22:17:12 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.152 2007/03/30 18:34:55 mha Exp $
* ----------
*/
#include "postgres.h"
@@ -135,6 +135,18 @@ static HTAB *pgStatDBHash = NULL;
static PgBackendStatus *localBackendStatusTable = NULL;
static int localNumBackends = 0;
+/*
+ * BgWriter global statistics counters, from bgwriter.c
+ */
+extern PgStat_MsgBgWriter BgWriterStats;
+
+/*
+ * Cluster wide statistics, kept in the stats collector.
+ * Contains statistics that are not collected per database
+ * or per table.
+ */
+static PgStat_GlobalStats globalStats;
+
static volatile bool need_exit = false;
static volatile bool need_statwrite = false;
@@ -171,6 +183,7 @@ static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len);
static void pgstat_recv_autovac(PgStat_MsgAutovacStart *msg, int len);
static void pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len);
static void pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len);
+static void pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len);
/* ------------------------------------------------------------
@@ -1288,6 +1301,22 @@ pgstat_fetch_stat_numbackends(void)
return localNumBackends;
}
+/*
+ * ---------
+ * pgstat_fetch_global() -
+ *
+ * Support function for the SQL-callable pgstat* functions. Returns
+ * a pointer to the global statistics struct.
+ * ---------
+ */
+PgStat_GlobalStats *
+pgstat_fetch_global(void)
+{
+ backend_read_statsfile();
+
+ return &globalStats;
+}
+
/* ------------------------------------------------------------
* Functions for management of the shared-memory PgBackendStatus array
@@ -1646,6 +1675,42 @@ pgstat_send(void *msg, int len)
#endif
}
+/* ----------
+ * pgstat_send_bgwriter() -
+ *
+ * Send bgwriter statistics to the collector
+ * ----------
+ */
+void
+pgstat_send_bgwriter(void)
+{
+ /*
+ * This function can be called even if nothing at all has happened.
+ * In this case, avoid sending a completely empty message to
+ * the stats collector.
+ */
+ if (BgWriterStats.m_timed_checkpoints == 0 &&
+ BgWriterStats.m_requested_checkpoints == 0 &&
+ BgWriterStats.m_buf_written_checkpoints == 0 &&
+ BgWriterStats.m_buf_written_lru == 0 &&
+ BgWriterStats.m_buf_written_all == 0 &&
+ BgWriterStats.m_maxwritten_lru == 0 &&
+ BgWriterStats.m_maxwritten_all == 0)
+ return;
+
+ /*
+ * Prepare and send the message
+ */
+ pgstat_setheader(&BgWriterStats.m_hdr, PGSTAT_MTYPE_BGWRITER);
+ pgstat_send(&BgWriterStats, sizeof(BgWriterStats));
+
+ /*
+ * Clear out the bgwriter statistics buffer, so it can be
+ * re-used.
+ */
+ memset(&BgWriterStats, 0, sizeof(BgWriterStats));
+}
+
/* ----------
* PgstatCollectorMain() -
@@ -1892,6 +1957,10 @@ PgstatCollectorMain(int argc, char *argv[])
pgstat_recv_analyze((PgStat_MsgAnalyze *) &msg, len);
break;
+ case PGSTAT_MTYPE_BGWRITER:
+ pgstat_recv_bgwriter((PgStat_MsgBgWriter *) &msg, len);
+ break;
+
default:
break;
}
@@ -2031,6 +2100,11 @@ pgstat_write_statsfile(void)
fwrite(&format_id, sizeof(format_id), 1, fpout);
/*
+ * Write global stats struct
+ */
+ fwrite(&globalStats, sizeof(globalStats), 1, fpout);
+
+ /*
* Walk through the database table.
*/
hash_seq_init(&hstat, pgStatDBHash);
@@ -2133,6 +2207,12 @@ pgstat_read_statsfile(Oid onlydb)
HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
/*
+ * Clear out global statistics so they start from zero in case we can't
+ * load an existing statsfile.
+ */
+ memset(&globalStats, 0, sizeof(globalStats));
+
+ /*
* Try to open the status file. If it doesn't exist, the backends simply
* return zero for anything and the collector simply starts from scratch
* with empty counters.
@@ -2152,6 +2232,16 @@ pgstat_read_statsfile(Oid onlydb)
}
/*
+ * Read global stats struct
+ */
+ if (fread(&globalStats, 1, sizeof(globalStats), fpin) != sizeof(globalStats))
+ {
+ ereport(pgStatRunningInCollector ? LOG : WARNING,
+ (errmsg("corrupted pgstat.stat file")));
+ goto done;
+ }
+
+ /*
* We found an existing collector stats file. Read it and put all the
* hashtable entries into place.
*/
@@ -2656,3 +2746,22 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len)
tabentry->n_dead_tuples = msg->m_dead_tuples;
tabentry->last_anl_tuples = msg->m_live_tuples + msg->m_dead_tuples;
}
+
+
+/* ----------
+ * pgstat_recv_bgwriter() -
+ *
+ * Process a BGWRITER message.
+ * ----------
+ */
+static void
+pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len)
+{
+ globalStats.timed_checkpoints += msg->m_timed_checkpoints;
+ globalStats.requested_checkpoints += msg->m_requested_checkpoints;
+ globalStats.buf_written_checkpoints += msg->m_buf_written_checkpoints;
+ globalStats.buf_written_lru += msg->m_buf_written_lru;
+ globalStats.buf_written_all += msg->m_buf_written_all;
+ globalStats.maxwritten_lru += msg->m_maxwritten_lru;
+ globalStats.maxwritten_all += msg->m_maxwritten_all;
+}