Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit adc4e1e

Browse files
committed
Fix vacuum so that autovacuum is really not cancelled when doing an emergency
job (i.e. to prevent Xid wraparound problems.) Bug reported by ITAGAKI Takahiro in 20080314103837.63D3.52131E4D@oss.ntt.co.jp, though I didn't use his patch.
1 parent be5d6df commit adc4e1e

File tree

4 files changed

+26
-21
lines changed

4 files changed

+26
-21
lines changed

src/backend/commands/vacuum.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.366 2008/03/10 02:04:08 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.367 2008/03/14 17:25:58 alvherre Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -209,7 +209,8 @@ static BufferAccessStrategy vac_strategy;
209209
static List *get_rel_oids(List *relids, const RangeVar *vacrel,
210210
const char *stmttype);
211211
static void vac_truncate_clog(TransactionId frozenXID);
212-
static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind);
212+
static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
213+
bool for_wraparound);
213214
static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt);
214215
static void scan_heap(VRelStats *vacrelstats, Relation onerel,
215216
VacPageList vacuum_pages, VacPageList fraged_pages);
@@ -263,6 +264,9 @@ static Size PageGetFreeSpaceWithFillFactor(Relation relation, Page page);
263264
* relation OIDs to be processed, and vacstmt->relation is ignored.
264265
* (The non-NIL case is currently only used by autovacuum.)
265266
*
267+
* for_wraparound is used by autovacuum to let us know when it's forcing
268+
* a vacuum for wraparound, which should not be auto-cancelled.
269+
*
266270
* bstrategy is normally given as NULL, but in autovacuum it can be passed
267271
* in to use the same buffer strategy object across multiple vacuum() calls.
268272
*
@@ -274,7 +278,7 @@ static Size PageGetFreeSpaceWithFillFactor(Relation relation, Page page);
274278
*/
275279
void
276280
vacuum(VacuumStmt *vacstmt, List *relids,
277-
BufferAccessStrategy bstrategy, bool isTopLevel)
281+
BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
278282
{
279283
const char *stmttype = vacstmt->vacuum ? "VACUUM" : "ANALYZE";
280284
volatile MemoryContext anl_context = NULL;
@@ -421,7 +425,7 @@ vacuum(VacuumStmt *vacstmt, List *relids,
421425
Oid relid = lfirst_oid(cur);
422426

423427
if (vacstmt->vacuum)
424-
vacuum_rel(relid, vacstmt, RELKIND_RELATION);
428+
vacuum_rel(relid, vacstmt, RELKIND_RELATION, for_wraparound);
425429

426430
if (vacstmt->analyze)
427431
{
@@ -966,7 +970,8 @@ vac_truncate_clog(TransactionId frozenXID)
966970
* At entry and exit, we are not inside a transaction.
967971
*/
968972
static void
969-
vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
973+
vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind,
974+
bool for_wraparound)
970975
{
971976
LOCKMODE lmode;
972977
Relation onerel;
@@ -999,13 +1004,19 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
9991004
* contents of other tables is arguably broken, but we won't break it
10001005
* here by violating transaction semantics.)
10011006
*
1007+
* We also set the VACUUM_FOR_WRAPAROUND flag, which is passed down
1008+
* by autovacuum; it's used to avoid cancelling a vacuum that was
1009+
* invoked in an emergency.
1010+
*
10021011
* Note: this flag remains set until CommitTransaction or
10031012
* AbortTransaction. We don't want to clear it until we reset
10041013
* MyProc->xid/xmin, else OldestXmin might appear to go backwards,
10051014
* which is probably Not Good.
10061015
*/
10071016
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
10081017
MyProc->vacuumFlags |= PROC_IN_VACUUM;
1018+
if (for_wraparound)
1019+
MyProc->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND;
10091020
LWLockRelease(ProcArrayLock);
10101021
}
10111022

@@ -1147,7 +1158,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
11471158
* totally unimportant for toast relations.
11481159
*/
11491160
if (toast_relid != InvalidOid)
1150-
vacuum_rel(toast_relid, vacstmt, RELKIND_TOASTVALUE);
1161+
vacuum_rel(toast_relid, vacstmt, RELKIND_TOASTVALUE, for_wraparound);
11511162

11521163
/*
11531164
* Now release the session-level lock on the master table.

src/backend/postmaster/autovacuum.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
*
5656
*
5757
* IDENTIFICATION
58-
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.72 2008/02/20 14:01:45 alvherre Exp $
58+
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.73 2008/03/14 17:25:58 alvherre Exp $
5959
*
6060
*-------------------------------------------------------------------------
6161
*/
@@ -285,6 +285,7 @@ static void relation_needs_vacanalyze(Oid relid, Form_pg_autovacuum avForm,
285285

286286
static void autovacuum_do_vac_analyze(Oid relid, bool dovacuum,
287287
bool doanalyze, int freeze_min_age,
288+
bool for_wraparound,
288289
BufferAccessStrategy bstrategy);
289290
static HeapTuple get_pg_autovacuum_tuple_relid(Relation avRel, Oid relid);
290291
static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared,
@@ -2095,14 +2096,6 @@ do_autovacuum(void)
20952096
/* clean up memory before each iteration */
20962097
MemoryContextResetAndDeleteChildren(PortalContext);
20972098

2098-
/* set the "vacuum for wraparound" flag in PGPROC */
2099-
if (tab->at_wraparound)
2100-
{
2101-
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
2102-
MyProc->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND;
2103-
LWLockRelease(ProcArrayLock);
2104-
}
2105-
21062099
/*
21072100
* Save the relation name for a possible error message, to avoid a
21082101
* catalog lookup in case of an error. Note: they must live in a
@@ -2126,6 +2119,7 @@ do_autovacuum(void)
21262119
tab->at_dovacuum,
21272120
tab->at_doanalyze,
21282121
tab->at_freeze_min_age,
2122+
tab->at_wraparound,
21292123
bstrategy);
21302124

21312125
/*
@@ -2604,7 +2598,7 @@ relation_needs_vacanalyze(Oid relid,
26042598
*/
26052599
static void
26062600
autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze,
2607-
int freeze_min_age,
2601+
int freeze_min_age, bool for_wraparound,
26082602
BufferAccessStrategy bstrategy)
26092603
{
26102604
VacuumStmt vacstmt;
@@ -2631,7 +2625,7 @@ autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze,
26312625
/* Let pgstat know what we're doing */
26322626
autovac_report_activity(&vacstmt, relid);
26332627

2634-
vacuum(&vacstmt, list_make1_oid(relid), bstrategy, true);
2628+
vacuum(&vacstmt, list_make1_oid(relid), bstrategy, for_wraparound, true);
26352629
MemoryContextSwitchTo(old_cxt);
26362630
}
26372631

src/backend/tcop/utility.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.289 2008/01/01 19:45:52 momjian Exp $
13+
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.290 2008/03/14 17:25:58 alvherre Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1032,7 +1032,7 @@ ProcessUtility(Node *parsetree,
10321032
break;
10331033

10341034
case T_VacuumStmt:
1035-
vacuum((VacuumStmt *) parsetree, NIL, NULL, isTopLevel);
1035+
vacuum((VacuumStmt *) parsetree, NIL, NULL, false, isTopLevel);
10361036
break;
10371037

10381038
case T_ExplainStmt:

src/include/commands/vacuum.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.75 2008/01/01 19:45:57 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.76 2008/03/14 17:25:59 alvherre Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -114,7 +114,7 @@ extern int vacuum_freeze_min_age;
114114

115115
/* in commands/vacuum.c */
116116
extern void vacuum(VacuumStmt *vacstmt, List *relids,
117-
BufferAccessStrategy bstrategy, bool isTopLevel);
117+
BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel);
118118
extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
119119
int *nindexes, Relation **Irel);
120120
extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);

0 commit comments

Comments
 (0)