5555 *
5656 *
5757 * IDENTIFICATION
58- * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.60 2007/09/2403 :12:23 tgl Exp $
58+ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.61 2007/09/2404 :12:01 alvherre Exp $
5959 *
6060 *-------------------------------------------------------------------------
6161 */
@@ -116,6 +116,9 @@ intautovacuum_vac_cost_limit;
116116
117117int Log_autovacuum_min_duration = -1 ;
118118
119+ /* how long to keep pgstat data in the launcher, in milliseconds */
120+ #define STATS_READ_DELAY 1000
121+
119122
120123/* Flags to tell if we are in an autovacuum process */
121124static bool am_autovacuum_launcher = false;
@@ -291,6 +294,7 @@ static void avl_sighup_handler(SIGNAL_ARGS);
291294static void avl_sigusr1_handler (SIGNAL_ARGS );
292295static void avl_sigterm_handler (SIGNAL_ARGS );
293296static void avl_quickdie (SIGNAL_ARGS );
297+ static void autovac_refresh_stats (void );
294298
295299
296300
@@ -488,7 +492,10 @@ AutoVacLauncherMain(int argc, char *argv[])
488492DatabaseListCxt = NULL ;
489493DatabaseList = NULL ;
490494
491- /* Make sure pgstat also considers our stat data as gone */
495+ /*
496+ * Make sure pgstat also considers our stat data as gone. Note: we
497+ * mustn't use autovac_refresh_stats here.
498+ */
492499pgstat_clear_snapshot ();
493500
494501/* Now we can allow interrupts again */
@@ -836,7 +843,7 @@ rebuild_database_list(Oid newdb)
836843HTAB * dbhash ;
837844
838845/* use fresh stats */
839- pgstat_clear_snapshot ();
846+ autovac_refresh_stats ();
840847
841848newcxt = AllocSetContextCreate (AutovacMemCxt ,
842849"AV dblist" ,
@@ -1063,7 +1070,7 @@ do_start_worker(void)
10631070oldcxt = MemoryContextSwitchTo (tmpcxt );
10641071
10651072/* use fresh stats */
1066- pgstat_clear_snapshot ();
1073+ autovac_refresh_stats ();
10671074
10681075/* Get a list of databases */
10691076dblist = get_database_list ();
@@ -1106,9 +1113,6 @@ do_start_worker(void)
11061113avw_dbase * tmp = lfirst (cell );
11071114Dlelem * elem ;
11081115
1109- /* Find pgstat entry if any */
1110- tmp -> adw_entry = pgstat_fetch_stat_dbentry (tmp -> adw_datid );
1111-
11121116/* Check to see if this one is at risk of wraparound */
11131117if (TransactionIdPrecedes (tmp -> adw_frozenxid ,xidForceLimit ))
11141118{
@@ -1121,9 +1125,12 @@ do_start_worker(void)
11211125else if (for_xid_wrap )
11221126continue ;/* ignore not-at-risk DBs */
11231127
1128+ /* Find pgstat entry if any */
1129+ tmp -> adw_entry = pgstat_fetch_stat_dbentry (tmp -> adw_datid );
1130+
11241131/*
1125- *Otherwise, skip a database with no pgstat entry; it means it
1126- *hasn't seen any activity.
1132+ *Skip a database with no pgstat entry; it means it hasn't seen any
1133+ * activity.
11271134 */
11281135if (!tmp -> adw_entry )
11291136continue ;
@@ -2258,7 +2265,7 @@ table_recheck_autovac(Oid relid)
22582265PgStat_StatDBEntry * dbentry ;
22592266
22602267/* use fresh stats */
2261- pgstat_clear_snapshot ();
2268+ autovac_refresh_stats ();
22622269
22632270shared = pgstat_fetch_stat_dbentry (InvalidOid );
22642271dbentry = pgstat_fetch_stat_dbentry (MyDatabaseId );
@@ -2725,3 +2732,35 @@ AutoVacuumShmemInit(void)
27252732else
27262733Assert (found );
27272734}
2735+
2736+ /*
2737+ * autovac_refresh_stats
2738+ * Refresh pgstats data for an autovacuum process
2739+ *
2740+ * Cause the next pgstats read operation to obtain fresh data, but throttle
2741+ * such refreshing in the autovacuum launcher. This is mostly to avoid
2742+ * rereading the pgstats files too many times in quick succession when there
2743+ * are many databases.
2744+ *
2745+ * Note: we avoid throttling in the autovac worker, as it would be
2746+ * counterproductive in the recheck logic.
2747+ */
2748+ static void
2749+ autovac_refresh_stats (void )
2750+ {
2751+ if (IsAutoVacuumLauncherProcess ())
2752+ {
2753+ static TimestampTz last_read = 0 ;
2754+ TimestampTz current_time ;
2755+
2756+ current_time = GetCurrentTimestamp ();
2757+
2758+ if (!TimestampDifferenceExceeds (last_read ,current_time ,
2759+ STATS_READ_DELAY ))
2760+ return ;
2761+
2762+ last_read = current_time ;
2763+ }
2764+
2765+ pgstat_clear_snapshot ();
2766+ }