1313 *
1414 *Copyright (c) 2001-2008, PostgreSQL Global Development Group
1515 *
16- *$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.177 2008/08/01 13:16:08 alvherre Exp $
16+ *$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.178 2008/08/05 12:09:30 mha Exp $
1717 * ----------
1818 */
1919#include "postgres.h"
6868 * Paths for the statistics files (relative to installation's $PGDATA).
6969 * ----------
7070 */
71- #define PGSTAT_STAT_FILENAME "global/pgstat.stat"
72- #define PGSTAT_STAT_TMPFILE "global/pgstat.tmp"
71+ #define PGSTAT_STAT_PERMANENT_FILENAME "global/pgstat.stat"
72+ #define PGSTAT_STAT_PERMANENT_TMPFILE "global/pgstat.tmp"
73+ #define PGSTAT_STAT_FILENAME "pg_stat_tmp/pgstat.stat"
74+ #define PGSTAT_STAT_TMPFILE "pg_stat_tmp/pgstat.tmp"
7375
7476/* ----------
7577 * Timer definitions.
@@ -219,8 +221,8 @@ static void force_statwrite(SIGNAL_ARGS);
219221static void pgstat_beshutdown_hook (int code ,Datum arg );
220222
221223static PgStat_StatDBEntry * pgstat_get_db_entry (Oid databaseid ,bool create );
222- static void pgstat_write_statsfile (void );
223- static HTAB * pgstat_read_statsfile (Oid onlydb );
224+ static void pgstat_write_statsfile (bool permanent );
225+ static HTAB * pgstat_read_statsfile (Oid onlydb , bool permanent );
224226static void backend_read_statsfile (void );
225227static void pgstat_read_current_status (void );
226228
510512pgstat_reset_all (void )
511513{
512514unlink (PGSTAT_STAT_FILENAME );
515+ unlink (PGSTAT_STAT_PERMANENT_FILENAME );
513516}
514517
515518#ifdef EXEC_BACKEND
@@ -2598,7 +2601,7 @@ PgstatCollectorMain(int argc, char *argv[])
25982601 * zero.
25992602 */
26002603pgStatRunningInCollector = true;
2601- pgStatDBHash = pgstat_read_statsfile (InvalidOid );
2604+ pgStatDBHash = pgstat_read_statsfile (InvalidOid , true );
26022605
26032606/*
26042607 * Setup the descriptor set for select(2).Since only one bit in the set
@@ -2638,7 +2641,7 @@ PgstatCollectorMain(int argc, char *argv[])
26382641if (!PostmasterIsAlive (true))
26392642break ;
26402643
2641- pgstat_write_statsfile ();
2644+ pgstat_write_statsfile (false );
26422645need_statwrite = false;
26432646need_timer = true;
26442647}
@@ -2806,7 +2809,7 @@ PgstatCollectorMain(int argc, char *argv[])
28062809/*
28072810 * Save the final stats to reuse at next startup.
28082811 */
2809- pgstat_write_statsfile ();
2812+ pgstat_write_statsfile (true );
28102813
28112814exit (0 );
28122815}
@@ -2891,10 +2894,14 @@ pgstat_get_db_entry(Oid databaseid, bool create)
28912894 * pgstat_write_statsfile() -
28922895 *
28932896 *Tell the news.
2897+ *If writing to the permanent file (happens when the collector is
2898+ *shutting down only), remove the temporary file so that backends
2899+ *starting up under a new postmaster can't read the old data before
2900+ *the new collector is ready.
28942901 * ----------
28952902 */
28962903static void
2897- pgstat_write_statsfile (void )
2904+ pgstat_write_statsfile (bool permanent )
28982905{
28992906HASH_SEQ_STATUS hstat ;
29002907HASH_SEQ_STATUS tstat ;
@@ -2904,17 +2911,19 @@ pgstat_write_statsfile(void)
29042911PgStat_StatFuncEntry * funcentry ;
29052912FILE * fpout ;
29062913int32 format_id ;
2914+ const char * tmpfile = permanent ?PGSTAT_STAT_PERMANENT_TMPFILE :PGSTAT_STAT_TMPFILE ;
2915+ const char * statfile = permanent ?PGSTAT_STAT_PERMANENT_FILENAME :PGSTAT_STAT_FILENAME ;
29072916
29082917/*
29092918 * Open the statistics temp file to write out the current values.
29102919 */
2911- fpout = fopen (PGSTAT_STAT_TMPFILE ,PG_BINARY_W );
2920+ fpout = fopen (tmpfile ,PG_BINARY_W );
29122921if (fpout == NULL )
29132922{
29142923ereport (LOG ,
29152924(errcode_for_file_access (),
29162925errmsg ("could not open temporary statistics file \"%s\": %m" ,
2917- PGSTAT_STAT_TMPFILE )));
2926+ tmpfile )));
29182927return ;
29192928}
29202929
@@ -2981,26 +2990,29 @@ pgstat_write_statsfile(void)
29812990ereport (LOG ,
29822991(errcode_for_file_access (),
29832992errmsg ("could not write temporary statistics file \"%s\": %m" ,
2984- PGSTAT_STAT_TMPFILE )));
2993+ tmpfile )));
29852994fclose (fpout );
2986- unlink (PGSTAT_STAT_TMPFILE );
2995+ unlink (tmpfile );
29872996}
29882997else if (fclose (fpout )< 0 )
29892998{
29902999ereport (LOG ,
29913000(errcode_for_file_access (),
29923001errmsg ("could not close temporary statistics file \"%s\": %m" ,
2993- PGSTAT_STAT_TMPFILE )));
2994- unlink (PGSTAT_STAT_TMPFILE );
3002+ tmpfile )));
3003+ unlink (tmpfile );
29953004}
2996- else if (rename (PGSTAT_STAT_TMPFILE , PGSTAT_STAT_FILENAME )< 0 )
3005+ else if (rename (tmpfile , statfile )< 0 )
29973006{
29983007ereport (LOG ,
29993008(errcode_for_file_access (),
30003009errmsg ("could not rename temporary statistics file \"%s\" to \"%s\": %m" ,
3001- PGSTAT_STAT_TMPFILE , PGSTAT_STAT_FILENAME )));
3002- unlink (PGSTAT_STAT_TMPFILE );
3010+ tmpfile , statfile )));
3011+ unlink (tmpfile );
30033012}
3013+
3014+ if (permanent )
3015+ unlink (PGSTAT_STAT_FILENAME );
30043016}
30053017
30063018
@@ -3012,7 +3024,7 @@ pgstat_write_statsfile(void)
30123024 * ----------
30133025 */
30143026static HTAB *
3015- pgstat_read_statsfile (Oid onlydb )
3027+ pgstat_read_statsfile (Oid onlydb , bool permanent )
30163028{
30173029PgStat_StatDBEntry * dbentry ;
30183030PgStat_StatDBEntry dbbuf ;
@@ -3027,6 +3039,7 @@ pgstat_read_statsfile(Oid onlydb)
30273039FILE * fpin ;
30283040int32 format_id ;
30293041bool found ;
3042+ const char * statfile = permanent ?PGSTAT_STAT_PERMANENT_FILENAME :PGSTAT_STAT_FILENAME ;
30303043
30313044/*
30323045 * The tables will live in pgStatLocalContext.
@@ -3055,7 +3068,7 @@ pgstat_read_statsfile(Oid onlydb)
30553068 * return zero for anything and the collector simply starts from scratch
30563069 * with empty counters.
30573070 */
3058- if ((fpin = AllocateFile (PGSTAT_STAT_FILENAME ,PG_BINARY_R ))== NULL )
3071+ if ((fpin = AllocateFile (statfile ,PG_BINARY_R ))== NULL )
30593072return dbhash ;
30603073
30613074/*
@@ -3244,6 +3257,9 @@ pgstat_read_statsfile(Oid onlydb)
32443257done :
32453258FreeFile (fpin );
32463259
3260+ if (permanent )
3261+ unlink (PGSTAT_STAT_PERMANENT_FILENAME );
3262+
32473263return dbhash ;
32483264}
32493265
@@ -3262,9 +3278,9 @@ backend_read_statsfile(void)
32623278
32633279/* Autovacuum launcher wants stats about all databases */
32643280if (IsAutoVacuumLauncherProcess ())
3265- pgStatDBHash = pgstat_read_statsfile (InvalidOid );
3281+ pgStatDBHash = pgstat_read_statsfile (InvalidOid , false );
32663282else
3267- pgStatDBHash = pgstat_read_statsfile (MyDatabaseId );
3283+ pgStatDBHash = pgstat_read_statsfile (MyDatabaseId , false );
32683284}
32693285
32703286