*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.60 2007/09/24 03:12:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.61 2007/09/24 04:12:01 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
int Log_autovacuum_min_duration = -1;
+/* how long to keep pgstat data in the launcher, in milliseconds */
+#define STATS_READ_DELAY 1000
+
/* Flags to tell if we are in an autovacuum process */
static bool am_autovacuum_launcher = false;
static void avl_sigusr1_handler(SIGNAL_ARGS);
static void avl_sigterm_handler(SIGNAL_ARGS);
static void avl_quickdie(SIGNAL_ARGS);
+static void autovac_refresh_stats(void);
DatabaseListCxt = NULL;
DatabaseList = NULL;
- /* Make sure pgstat also considers our stat data as gone */
+ /*
+ * Make sure pgstat also considers our stat data as gone. Note: we
+ * mustn't use autovac_refresh_stats here.
+ */
pgstat_clear_snapshot();
/* Now we can allow interrupts again */
HTAB *dbhash;
/* use fresh stats */
- pgstat_clear_snapshot();
+ autovac_refresh_stats();
newcxt = AllocSetContextCreate(AutovacMemCxt,
"AV dblist",
oldcxt = MemoryContextSwitchTo(tmpcxt);
/* use fresh stats */
- pgstat_clear_snapshot();
+ autovac_refresh_stats();
/* Get a list of databases */
dblist = get_database_list();
avw_dbase *tmp = lfirst(cell);
Dlelem *elem;
- /* Find pgstat entry if any */
- tmp->adw_entry = pgstat_fetch_stat_dbentry(tmp->adw_datid);
-
/* Check to see if this one is at risk of wraparound */
if (TransactionIdPrecedes(tmp->adw_frozenxid, xidForceLimit))
{
else if (for_xid_wrap)
continue; /* ignore not-at-risk DBs */
+ /* Find pgstat entry if any */
+ tmp->adw_entry = pgstat_fetch_stat_dbentry(tmp->adw_datid);
+
/*
- * Otherwise, skip a database with no pgstat entry; it means it
- * hasn't seen any activity.
+ * Skip a database with no pgstat entry; it means it hasn't seen any
+ * activity.
*/
if (!tmp->adw_entry)
continue;
PgStat_StatDBEntry *dbentry;
/* use fresh stats */
- pgstat_clear_snapshot();
+ autovac_refresh_stats();
shared = pgstat_fetch_stat_dbentry(InvalidOid);
dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId);
else
Assert(found);
}
+
+/*
+ * autovac_refresh_stats
+ * Refresh pgstats data for an autovacuum process
+ *
+ * Cause the next pgstats read operation to obtain fresh data, but throttle
+ * such refreshing in the autovacuum launcher. This is mostly to avoid
+ * rereading the pgstats files too many times in quick succession when there
+ * are many databases.
+ *
+ * Note: we avoid throttling in the autovac worker, as it would be
+ * counterproductive in the recheck logic.
+ */
+static void
+autovac_refresh_stats(void)
+{
+ if (IsAutoVacuumLauncherProcess())
+ {
+ static TimestampTz last_read = 0;
+ TimestampTz current_time;
+
+ current_time = GetCurrentTimestamp();
+
+ if (!TimestampDifferenceExceeds(last_read, current_time,
+ STATS_READ_DELAY))
+ return;
+
+ last_read = current_time;
+ }
+
+ pgstat_clear_snapshot();
+}