From 5b8eb2b4b95ac4b016368ce6ca2c3477387e7fc7 Mon Sep 17 00:00:00 2001
From: Magnus Hagander <magnus@hagander.net>
Date: Fri, 15 Aug 2008 08:37:41 +0000
Subject: [PATCH] Make the temporary directory for pgstat files configurable by
 the GUC variable stats_temp_directory, instead of requiring the admin to
 mount/symlink the pg_stat_tmp directory manually.

For now the config variable is PGC_POSTMASTER. Room for further improvment
that would allow it to be changed on-the-fly.
---
 doc/src/sgml/config.sgml                      | 18 +++++++++-
 doc/src/sgml/monitoring.sgml                  |  6 ++--
 src/backend/postmaster/pgstat.c               | 21 ++++++-----
 src/backend/utils/misc/guc.c                  | 35 ++++++++++++++++++-
 src/backend/utils/misc/postgresql.conf.sample |  1 +
 src/include/pgstat.h                          |  4 ++-
 6 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 6e65251746c..16a309547b1 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.184 2008/07/18 17:33:17 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.185 2008/08/15 08:37:41 mha Exp $ -->
 
 <chapter Id="runtime-config">
   <title>Server Configuration</title>
@@ -3394,6 +3394,22 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-stats-temp-directory" xreflabel="stats_temp_directory">
+      <term><varname>stats_temp_directory</varname> (<type>string</type>)</term>
+      <indexterm>
+       <primary><varname>stats_temp_directory</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Sets the directory to store temporary statistics data in. This can be a 
+        path relative to the data directory or an absolute path. The default is
+        <filename>pg_stat_tmp</filename>. Pointing this at a RAM based filesystem
+        will decrease physical I/O requirements and can lead to increased 
+        performance. This parameter can only be set at server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
      </variablelist>
     </sect2>
 
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 29a3e107030..ab30d87202a 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.61 2008/08/05 12:09:30 mha Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/monitoring.sgml,v 1.62 2008/08/15 08:37:41 mha Exp $ -->
 
 <chapter id="monitoring">
  <title>Monitoring Database Activity</title>
@@ -171,8 +171,8 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
    These files are stored in the <filename>pg_stat_tmp</filename> subdirectory.
    When the postmaster shuts down, a permanent copy of the statistics
    data is stored in the <filename>global</filename> subdirectory. For increased
-   performance, it is possible to mount or symlink a RAM based
-   filesystem to the <filename>pg_stat_tmp</filename> directory.
+   performance, the parameter <xref linkend="guc-stats-temp-directory"> can
+   be pointed at a RAM based filesystem, decreasing physical I/O requirements.
   </para>
 
  </sect2>
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index f78e8840b2f..e09becdeb80 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.178 2008/08/05 12:09:30 mha Exp $
+ *	$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.179 2008/08/15 08:37:39 mha Exp $
  * ----------
  */
 #include "postgres.h"
@@ -70,8 +70,6 @@
  */
 #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.
@@ -106,6 +104,13 @@ bool		pgstat_track_counts = false;
 int			pgstat_track_functions = TRACK_FUNC_OFF;
 int			pgstat_track_activity_query_size = 1024;
 
+/* ----------
+ * Built from GUC parameter
+ * ----------
+ */
+char	   *pgstat_stat_filename = NULL;
+char	   *pgstat_stat_tmpname = NULL;
+
 /*
  * BgWriter global statistics counters (unused in other processes).
  * Stored directly in a stats message structure so it can be sent
@@ -511,7 +516,7 @@ startup_failed:
 void
 pgstat_reset_all(void)
 {
-	unlink(PGSTAT_STAT_FILENAME);
+	unlink(pgstat_stat_filename);
 	unlink(PGSTAT_STAT_PERMANENT_FILENAME);
 }
 
@@ -2911,8 +2916,8 @@ pgstat_write_statsfile(bool permanent)
 	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;
+	const char *tmpfile = permanent?PGSTAT_STAT_PERMANENT_TMPFILE:pgstat_stat_tmpname;
+	const char *statfile = permanent?PGSTAT_STAT_PERMANENT_FILENAME:pgstat_stat_filename;
 
 	/*
 	 * Open the statistics temp file to write out the current values.
@@ -3012,7 +3017,7 @@ pgstat_write_statsfile(bool permanent)
 	}
 
 	if (permanent)
-		unlink(PGSTAT_STAT_FILENAME);
+		unlink(pgstat_stat_filename);
 }
 
 
@@ -3039,7 +3044,7 @@ pgstat_read_statsfile(Oid onlydb, bool permanent)
 	FILE	   *fpin;
 	int32		format_id;
 	bool		found;
-	const char *statfile = permanent?PGSTAT_STAT_PERMANENT_FILENAME:PGSTAT_STAT_FILENAME;
+	const char *statfile = permanent?PGSTAT_STAT_PERMANENT_FILENAME:pgstat_stat_filename;
 
 	/*
 	 * The tables will live in pgStatLocalContext.
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 874d20c15f1..6cc6dcb7e03 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.465 2008/07/23 17:29:53 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.466 2008/08/15 08:37:40 mha Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -164,6 +164,7 @@ static const char *show_tcp_keepalives_interval(void);
 static const char *show_tcp_keepalives_count(void);
 static bool assign_autovacuum_max_workers(int newval, bool doit, GucSource source);
 static bool assign_maxconnections(int newval, bool doit, GucSource source);
+static const char *assign_pgstat_temp_directory(const char *newval, bool doit, GucSource source);
 
 static char *config_enum_get_options(struct config_enum *record, 
 									 const char *prefix, const char *suffix);
@@ -343,6 +344,8 @@ char	   *HbaFileName;
 char	   *IdentFileName;
 char	   *external_pid_file;
 
+char	   *pgstat_temp_directory;
+
 int			tcp_keepalives_idle;
 int			tcp_keepalives_interval;
 int			tcp_keepalives_count;
@@ -2466,6 +2469,16 @@ static struct config_string ConfigureNamesString[] =
 		NULL, assign_canonical_path, NULL
 	},
 
+	{
+		{"stats_temp_directory", PGC_POSTMASTER, STATS_COLLECTOR,
+			gettext_noop("Writes temporary statistics files to the specified directory."),
+			NULL,
+			GUC_SUPERUSER_ONLY
+		},
+		&pgstat_temp_directory,
+		"pg_stat_tmp", assign_pgstat_temp_directory, NULL
+	},
+
 	{
 		{"default_text_search_config", PGC_USERSET, CLIENT_CONN_LOCALE,
 			gettext_noop("Sets default text search configuration."),
@@ -7370,4 +7383,24 @@ assign_autovacuum_max_workers(int newval, bool doit, GucSource source)
 	return true;
 }
 
+static const char *
+assign_pgstat_temp_directory(const char *newval, bool doit, GucSource source)
+{
+	if (doit)
+	{
+		if (pgstat_stat_tmpname)
+			free(pgstat_stat_tmpname);
+		if (pgstat_stat_filename)
+			free(pgstat_stat_filename);
+
+		pgstat_stat_tmpname = guc_malloc(FATAL, strlen(newval) + 12);  /* /pgstat.tmp */
+		pgstat_stat_filename = guc_malloc(FATAL, strlen(newval) + 13); /* /pgstat.stat */
+
+		sprintf(pgstat_stat_tmpname, "%s/pgstat.tmp", newval);
+		sprintf(pgstat_stat_filename, "%s/pgstat.stat", newval);
+	}
+
+	return newval;
+}
+
 #include "guc-file.c"
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 552d856ae29..063d3ec1c4a 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -366,6 +366,7 @@
 #track_functions = none			# none, pl, all
 #track_activity_query_size = 1024
 #update_process_title = on
+#stats_temp_directory = 'pg_stat_tmp'
 
 
 # - Statistics Monitoring -
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index fabc5fb4a07..8c2d39e4c55 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -5,7 +5,7 @@
  *
  *	Copyright (c) 2001-2008, PostgreSQL Global Development Group
  *
- *	$PostgreSQL: pgsql/src/include/pgstat.h,v 1.77 2008/06/30 10:58:47 heikki Exp $
+ *	$PostgreSQL: pgsql/src/include/pgstat.h,v 1.78 2008/08/15 08:37:40 mha Exp $
  * ----------
  */
 #ifndef PGSTAT_H
@@ -576,6 +576,8 @@ extern bool pgstat_track_activities;
 extern bool pgstat_track_counts;
 extern int	pgstat_track_functions;
 extern int	pgstat_track_activity_query_size;
+extern char *pgstat_stat_tmpname;
+extern char *pgstat_stat_filename;
 
 /*
  * BgWriter statistics counters are updated directly by bgwriter and bufmgr
-- 
GitLab