55
55
*
56
56
*
57
57
* IDENTIFICATION
58
- * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.62 2007/10/24 19:08:25 alvherre Exp $
58
+ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.63 2007/10/24 20:55:36 alvherre Exp $
59
59
*
60
60
*-------------------------------------------------------------------------
61
61
*/
@@ -172,6 +172,7 @@ typedef struct autovac_table
172
172
int at_freeze_min_age ;
173
173
int at_vacuum_cost_delay ;
174
174
int at_vacuum_cost_limit ;
175
+ bool at_wraparound ;
175
176
} autovac_table ;
176
177
177
178
/*-------------
@@ -280,7 +281,7 @@ static autovac_table *table_recheck_autovac(Oid relid);
280
281
static void relation_needs_vacanalyze (Oid relid , Form_pg_autovacuum avForm ,
281
282
Form_pg_class classForm ,
282
283
PgStat_StatTabEntry * tabentry , bool * dovacuum ,
283
- bool * doanalyze );
284
+ bool * doanalyze , bool * wraparound );
284
285
285
286
static void autovacuum_do_vac_analyze (Oid relid , bool dovacuum ,
286
287
bool doanalyze , int freeze_min_age ,
@@ -1440,9 +1441,6 @@ AutoVacWorkerMain(int argc, char *argv[])
1440
1441
/* Identify myself via ps */
1441
1442
init_ps_display ("autovacuum worker process" , "" , "" , "" );
1442
1443
1443
- if (PostAuthDelay )
1444
- pg_usleep (PostAuthDelay * 1000000L );
1445
-
1446
1444
SetProcessingMode (InitProcessing );
1447
1445
1448
1446
/*
@@ -1601,6 +1599,9 @@ AutoVacWorkerMain(int argc, char *argv[])
1601
1599
ereport (DEBUG1 ,
1602
1600
(errmsg ("autovacuum: processing database \"%s\"" , dbname )));
1603
1601
1602
+ if (PostAuthDelay )
1603
+ pg_usleep (PostAuthDelay * 1000000L );
1604
+
1604
1605
/* And do an appropriate amount of work */
1605
1606
recentXid = ReadNewTransactionId ();
1606
1607
do_autovacuum ();
@@ -2085,6 +2086,14 @@ do_autovacuum(void)
2085
2086
/* clean up memory before each iteration */
2086
2087
MemoryContextResetAndDeleteChildren (PortalContext );
2087
2088
2089
+ /* set the "vacuum for wraparound" flag in PGPROC */
2090
+ if (tab -> at_wraparound )
2091
+ {
2092
+ LWLockAcquire (ProcArrayLock , LW_EXCLUSIVE );
2093
+ MyProc -> vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND ;
2094
+ LWLockRelease (ProcArrayLock );
2095
+ }
2096
+
2088
2097
/*
2089
2098
* We will abort vacuuming the current table if something errors out,
2090
2099
* and continue with the next one in schedule; in particular, this
@@ -2119,6 +2128,7 @@ do_autovacuum(void)
2119
2128
get_rel_name (tab -> at_relid ));
2120
2129
EmitErrorReport ();
2121
2130
2131
+ /* this resets the PGPROC flags too */
2122
2132
AbortOutOfAnyTransaction ();
2123
2133
FlushErrorState ();
2124
2134
MemoryContextResetAndDeleteChildren (PortalContext );
@@ -2129,6 +2139,14 @@ do_autovacuum(void)
2129
2139
}
2130
2140
PG_END_TRY ();
2131
2141
2142
+ /* reset my PGPROC flag */
2143
+ if (tab -> at_wraparound )
2144
+ {
2145
+ LWLockAcquire (ProcArrayLock , LW_EXCLUSIVE );
2146
+ MyProc -> vacuumFlags &= ~PROC_VACUUM_FOR_WRAPAROUND ;
2147
+ LWLockRelease (ProcArrayLock );
2148
+ }
2149
+
2132
2150
/* be tidy */
2133
2151
pfree (tab );
2134
2152
@@ -2223,9 +2241,10 @@ relation_check_autovac(Oid relid, Form_pg_class classForm,
2223
2241
{
2224
2242
bool dovacuum ;
2225
2243
bool doanalyze ;
2244
+ bool dummy ;
2226
2245
2227
2246
relation_needs_vacanalyze (relid , avForm , classForm , tabentry ,
2228
- & dovacuum , & doanalyze );
2247
+ & dovacuum , & doanalyze , & dummy );
2229
2248
2230
2249
if (classForm -> relkind == RELKIND_TOASTVALUE )
2231
2250
{
@@ -2272,6 +2291,8 @@ table_recheck_autovac(Oid relid)
2272
2291
bool doit = false;
2273
2292
PgStat_StatDBEntry * shared ;
2274
2293
PgStat_StatDBEntry * dbentry ;
2294
+ bool wraparound ,
2295
+ toast_wraparound = false;
2275
2296
2276
2297
/* use fresh stats */
2277
2298
autovac_refresh_stats ();
@@ -2298,7 +2319,7 @@ table_recheck_autovac(Oid relid)
2298
2319
shared , dbentry );
2299
2320
2300
2321
relation_needs_vacanalyze (relid , avForm , classForm , tabentry ,
2301
- & dovacuum , & doanalyze );
2322
+ & dovacuum , & doanalyze , & wraparound );
2302
2323
2303
2324
/* OK, it needs vacuum by itself */
2304
2325
if (dovacuum )
@@ -2316,6 +2337,7 @@ table_recheck_autovac(Oid relid)
2316
2337
{
2317
2338
bool toast_dovacuum ;
2318
2339
bool toast_doanalyze ;
2340
+ bool toast_wraparound ;
2319
2341
Form_pg_class toastClassForm ;
2320
2342
PgStat_StatTabEntry * toasttabentry ;
2321
2343
@@ -2325,9 +2347,10 @@ table_recheck_autovac(Oid relid)
2325
2347
shared , dbentry );
2326
2348
2327
2349
/* note we use the pg_autovacuum entry for the main table */
2328
- relation_needs_vacanalyze (toastrelid , avForm , toastClassForm ,
2329
- toasttabentry , & toast_dovacuum ,
2330
- & toast_doanalyze );
2350
+ relation_needs_vacanalyze (toastrelid , avForm ,
2351
+ toastClassForm , toasttabentry ,
2352
+ & toast_dovacuum , & toast_doanalyze ,
2353
+ & toast_wraparound );
2331
2354
/* we only consider VACUUM for toast tables */
2332
2355
if (toast_dovacuum )
2333
2356
{
@@ -2389,6 +2412,7 @@ table_recheck_autovac(Oid relid)
2389
2412
tab -> at_freeze_min_age = freeze_min_age ;
2390
2413
tab -> at_vacuum_cost_limit = vac_cost_limit ;
2391
2414
tab -> at_vacuum_cost_delay = vac_cost_delay ;
2415
+ tab -> at_wraparound = wraparound || toast_wraparound ;
2392
2416
}
2393
2417
2394
2418
heap_close (avRel , AccessShareLock );
@@ -2403,7 +2427,8 @@ table_recheck_autovac(Oid relid)
2403
2427
* relation_needs_vacanalyze
2404
2428
*
2405
2429
* Check whether a relation needs to be vacuumed or analyzed; return each into
2406
- * "dovacuum" and "doanalyze", respectively. avForm and tabentry can be NULL,
2430
+ * "dovacuum" and "doanalyze", respectively. Also return whether the vacuum is
2431
+ * being forced because of Xid wraparound. avForm and tabentry can be NULL,
2407
2432
* classForm shouldn't.
2408
2433
*
2409
2434
* A table needs to be vacuumed if the number of dead tuples exceeds a
@@ -2437,7 +2462,8 @@ relation_needs_vacanalyze(Oid relid,
2437
2462
PgStat_StatTabEntry * tabentry ,
2438
2463
/* output params below */
2439
2464
bool * dovacuum ,
2440
- bool * doanalyze )
2465
+ bool * doanalyze ,
2466
+ bool * wraparound )
2441
2467
{
2442
2468
bool force_vacuum ;
2443
2469
float4 reltuples ; /* pg_class.reltuples */
@@ -2499,6 +2525,7 @@ relation_needs_vacanalyze(Oid relid,
2499
2525
force_vacuum = (TransactionIdIsNormal (classForm -> relfrozenxid ) &&
2500
2526
TransactionIdPrecedes (classForm -> relfrozenxid ,
2501
2527
xidForceLimit ));
2528
+ * wraparound = force_vacuum ;
2502
2529
2503
2530
/* User disabled it in pg_autovacuum? (But ignore if at risk) */
2504
2531
if (avForm && !avForm -> enabled && !force_vacuum )
0 commit comments