From 70d756970b7b2e93e6f807f5c55e2ad7727e212a Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Tue, 5 Aug 2008 12:09:30 +0000 Subject: [PATCH] Move pgstat.tmp into a temporary directory under $PGDATA named pg_stat_tmp. This allows the use of a ramdrive (either through mount or symlink) for the temporary file that's written every half second, which should reduce I/O. On server shutdown/startup, the file is written to the old location in the global directory, to preserve data across restarts. Bump catversion since the $PGDATA directory layout changed. --- doc/src/sgml/monitoring.sgml | 13 ++++++- doc/src/sgml/storage.sgml | 8 ++++- src/backend/postmaster/pgstat.c | 60 ++++++++++++++++++++------------ src/bin/initdb/initdb.c | 5 +-- src/include/catalog/catversion.h | 4 +-- 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 0d56e39d6f..29a3e10703 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -1,4 +1,4 @@ - + Monitoring Database Activity @@ -164,6 +164,17 @@ postgres: user database host SET.) + + + The statistics collector communicates with the backends needing + information (including autovacuum) through temporary files. + These files are stored in the pg_stat_tmp subdirectory. + When the postmaster shuts down, a permanent copy of the statistics + data is stored in the global subdirectory. For increased + performance, it is possible to mount or symlink a RAM based + filesystem to the pg_stat_tmp directory. + + diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml index 0303a2b3d4..e564fd2be9 100644 --- a/doc/src/sgml/storage.sgml +++ b/doc/src/sgml/storage.sgml @@ -1,4 +1,4 @@ - + @@ -77,6 +77,12 @@ Item (used for shared row locks) + + pg_stat_tmp + Subdirectory containing temporary files for the statistics + subsystem + + pg_subtrans Subdirectory containing subtransaction status data diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index d0e190aa44..f78e8840b2 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2008, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.177 2008/08/01 13:16:08 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.178 2008/08/05 12:09:30 mha Exp $ * ---------- */ #include "postgres.h" @@ -68,8 +68,10 @@ * Paths for the statistics files (relative to installation's $PGDATA). * ---------- */ -#define PGSTAT_STAT_FILENAME "global/pgstat.stat" -#define PGSTAT_STAT_TMPFILE "global/pgstat.tmp" +#define PGSTAT_STAT_PERMANENT_FILENAME "global/pgstat.stat" +#define PGSTAT_STAT_PERMANENT_TMPFILE "global/pgstat.tmp" +#define PGSTAT_STAT_FILENAME "pg_stat_tmp/pgstat.stat" +#define PGSTAT_STAT_TMPFILE "pg_stat_tmp/pgstat.tmp" /* ---------- * Timer definitions. @@ -219,8 +221,8 @@ static void force_statwrite(SIGNAL_ARGS); static void pgstat_beshutdown_hook(int code, Datum arg); static PgStat_StatDBEntry *pgstat_get_db_entry(Oid databaseid, bool create); -static void pgstat_write_statsfile(void); -static HTAB *pgstat_read_statsfile(Oid onlydb); +static void pgstat_write_statsfile(bool permanent); +static HTAB *pgstat_read_statsfile(Oid onlydb, bool permanent); static void backend_read_statsfile(void); static void pgstat_read_current_status(void); @@ -510,6 +512,7 @@ void pgstat_reset_all(void) { unlink(PGSTAT_STAT_FILENAME); + unlink(PGSTAT_STAT_PERMANENT_FILENAME); } #ifdef EXEC_BACKEND @@ -2598,7 +2601,7 @@ PgstatCollectorMain(int argc, char *argv[]) * zero. */ pgStatRunningInCollector = true; - pgStatDBHash = pgstat_read_statsfile(InvalidOid); + pgStatDBHash = pgstat_read_statsfile(InvalidOid, true); /* * Setup the descriptor set for select(2). Since only one bit in the set @@ -2638,7 +2641,7 @@ PgstatCollectorMain(int argc, char *argv[]) if (!PostmasterIsAlive(true)) break; - pgstat_write_statsfile(); + pgstat_write_statsfile(false); need_statwrite = false; need_timer = true; } @@ -2806,7 +2809,7 @@ PgstatCollectorMain(int argc, char *argv[]) /* * Save the final stats to reuse at next startup. */ - pgstat_write_statsfile(); + pgstat_write_statsfile(true); exit(0); } @@ -2891,10 +2894,14 @@ pgstat_get_db_entry(Oid databaseid, bool create) * pgstat_write_statsfile() - * * Tell the news. + * If writing to the permanent file (happens when the collector is + * shutting down only), remove the temporary file so that backends + * starting up under a new postmaster can't read the old data before + * the new collector is ready. * ---------- */ static void -pgstat_write_statsfile(void) +pgstat_write_statsfile(bool permanent) { HASH_SEQ_STATUS hstat; HASH_SEQ_STATUS tstat; @@ -2904,17 +2911,19 @@ pgstat_write_statsfile(void) PgStat_StatFuncEntry *funcentry; FILE *fpout; int32 format_id; + const char *tmpfile = permanent?PGSTAT_STAT_PERMANENT_TMPFILE:PGSTAT_STAT_TMPFILE; + const char *statfile = permanent?PGSTAT_STAT_PERMANENT_FILENAME:PGSTAT_STAT_FILENAME; /* * Open the statistics temp file to write out the current values. */ - fpout = fopen(PGSTAT_STAT_TMPFILE, PG_BINARY_W); + fpout = fopen(tmpfile, PG_BINARY_W); if (fpout == NULL) { ereport(LOG, (errcode_for_file_access(), errmsg("could not open temporary statistics file \"%s\": %m", - PGSTAT_STAT_TMPFILE))); + tmpfile))); return; } @@ -2981,26 +2990,29 @@ pgstat_write_statsfile(void) ereport(LOG, (errcode_for_file_access(), errmsg("could not write temporary statistics file \"%s\": %m", - PGSTAT_STAT_TMPFILE))); + tmpfile))); fclose(fpout); - unlink(PGSTAT_STAT_TMPFILE); + unlink(tmpfile); } else if (fclose(fpout) < 0) { ereport(LOG, (errcode_for_file_access(), errmsg("could not close temporary statistics file \"%s\": %m", - PGSTAT_STAT_TMPFILE))); - unlink(PGSTAT_STAT_TMPFILE); + tmpfile))); + unlink(tmpfile); } - else if (rename(PGSTAT_STAT_TMPFILE, PGSTAT_STAT_FILENAME) < 0) + else if (rename(tmpfile, statfile) < 0) { ereport(LOG, (errcode_for_file_access(), errmsg("could not rename temporary statistics file \"%s\" to \"%s\": %m", - PGSTAT_STAT_TMPFILE, PGSTAT_STAT_FILENAME))); - unlink(PGSTAT_STAT_TMPFILE); + tmpfile, statfile))); + unlink(tmpfile); } + + if (permanent) + unlink(PGSTAT_STAT_FILENAME); } @@ -3012,7 +3024,7 @@ pgstat_write_statsfile(void) * ---------- */ static HTAB * -pgstat_read_statsfile(Oid onlydb) +pgstat_read_statsfile(Oid onlydb, bool permanent) { PgStat_StatDBEntry *dbentry; PgStat_StatDBEntry dbbuf; @@ -3027,6 +3039,7 @@ pgstat_read_statsfile(Oid onlydb) FILE *fpin; int32 format_id; bool found; + const char *statfile = permanent?PGSTAT_STAT_PERMANENT_FILENAME:PGSTAT_STAT_FILENAME; /* * The tables will live in pgStatLocalContext. @@ -3055,7 +3068,7 @@ pgstat_read_statsfile(Oid onlydb) * return zero for anything and the collector simply starts from scratch * with empty counters. */ - if ((fpin = AllocateFile(PGSTAT_STAT_FILENAME, PG_BINARY_R)) == NULL) + if ((fpin = AllocateFile(statfile, PG_BINARY_R)) == NULL) return dbhash; /* @@ -3244,6 +3257,9 @@ pgstat_read_statsfile(Oid onlydb) done: FreeFile(fpin); + if (permanent) + unlink(PGSTAT_STAT_PERMANENT_FILENAME); + return dbhash; } @@ -3262,9 +3278,9 @@ backend_read_statsfile(void) /* Autovacuum launcher wants stats about all databases */ if (IsAutoVacuumLauncherProcess()) - pgStatDBHash = pgstat_read_statsfile(InvalidOid); + pgStatDBHash = pgstat_read_statsfile(InvalidOid, false); else - pgStatDBHash = pgstat_read_statsfile(MyDatabaseId); + pgStatDBHash = pgstat_read_statsfile(MyDatabaseId, false); } diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index a7ef3c9227..e305c69fa3 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -42,7 +42,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * Portions taken from FreeBSD. * - * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.158 2008/07/19 04:01:29 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.159 2008/08/05 12:09:30 mha Exp $ * *------------------------------------------------------------------------- */ @@ -2461,7 +2461,8 @@ main(int argc, char *argv[]) "pg_multixact/offsets", "base", "base/1", - "pg_tblspc" + "pg_tblspc", + "pg_stat_tmp" }; progname = get_progname(argv[0]); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 49d2a32431..6be25b05f9 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.474 2008/08/02 21:32:00 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.475 2008/08/05 12:09:30 mha Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200808011 +#define CATALOG_VERSION_NO 200808051 #endif