55
55
*
56
56
*
57
57
* IDENTIFICATION
58
- * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.60 2007/09/24 03 :12:23 tgl Exp $
58
+ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.61 2007/09/24 04 :12:01 alvherre Exp $
59
59
*
60
60
*-------------------------------------------------------------------------
61
61
*/
@@ -116,6 +116,9 @@ int autovacuum_vac_cost_limit;
116
116
117
117
int Log_autovacuum_min_duration = -1 ;
118
118
119
+ /* how long to keep pgstat data in the launcher, in milliseconds */
120
+ #define STATS_READ_DELAY 1000
121
+
119
122
120
123
/* Flags to tell if we are in an autovacuum process */
121
124
static bool am_autovacuum_launcher = false;
@@ -291,6 +294,7 @@ static void avl_sighup_handler(SIGNAL_ARGS);
291
294
static void avl_sigusr1_handler (SIGNAL_ARGS );
292
295
static void avl_sigterm_handler (SIGNAL_ARGS );
293
296
static void avl_quickdie (SIGNAL_ARGS );
297
+ static void autovac_refresh_stats (void );
294
298
295
299
296
300
@@ -488,7 +492,10 @@ AutoVacLauncherMain(int argc, char *argv[])
488
492
DatabaseListCxt = NULL ;
489
493
DatabaseList = NULL ;
490
494
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
+ */
492
499
pgstat_clear_snapshot ();
493
500
494
501
/* Now we can allow interrupts again */
@@ -836,7 +843,7 @@ rebuild_database_list(Oid newdb)
836
843
HTAB * dbhash ;
837
844
838
845
/* use fresh stats */
839
- pgstat_clear_snapshot ();
846
+ autovac_refresh_stats ();
840
847
841
848
newcxt = AllocSetContextCreate (AutovacMemCxt ,
842
849
"AV dblist" ,
@@ -1063,7 +1070,7 @@ do_start_worker(void)
1063
1070
oldcxt = MemoryContextSwitchTo (tmpcxt );
1064
1071
1065
1072
/* use fresh stats */
1066
- pgstat_clear_snapshot ();
1073
+ autovac_refresh_stats ();
1067
1074
1068
1075
/* Get a list of databases */
1069
1076
dblist = get_database_list ();
@@ -1106,9 +1113,6 @@ do_start_worker(void)
1106
1113
avw_dbase * tmp = lfirst (cell );
1107
1114
Dlelem * elem ;
1108
1115
1109
- /* Find pgstat entry if any */
1110
- tmp -> adw_entry = pgstat_fetch_stat_dbentry (tmp -> adw_datid );
1111
-
1112
1116
/* Check to see if this one is at risk of wraparound */
1113
1117
if (TransactionIdPrecedes (tmp -> adw_frozenxid , xidForceLimit ))
1114
1118
{
@@ -1121,9 +1125,12 @@ do_start_worker(void)
1121
1125
else if (for_xid_wrap )
1122
1126
continue ; /* ignore not-at-risk DBs */
1123
1127
1128
+ /* Find pgstat entry if any */
1129
+ tmp -> adw_entry = pgstat_fetch_stat_dbentry (tmp -> adw_datid );
1130
+
1124
1131
/*
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.
1127
1134
*/
1128
1135
if (!tmp -> adw_entry )
1129
1136
continue ;
@@ -2258,7 +2265,7 @@ table_recheck_autovac(Oid relid)
2258
2265
PgStat_StatDBEntry * dbentry ;
2259
2266
2260
2267
/* use fresh stats */
2261
- pgstat_clear_snapshot ();
2268
+ autovac_refresh_stats ();
2262
2269
2263
2270
shared = pgstat_fetch_stat_dbentry (InvalidOid );
2264
2271
dbentry = pgstat_fetch_stat_dbentry (MyDatabaseId );
@@ -2725,3 +2732,35 @@ AutoVacuumShmemInit(void)
2725
2732
else
2726
2733
Assert (found );
2727
2734
}
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
+ }
0 commit comments