Alvaro Herrera wrote: > Tom Lane wrote: > > That's really, really ugly. I'd rather see the flag passed down to > > vacuum_rel as a regular function argument. I realize you'll need > > to touch the signatures of a couple of levels of functions to do that, > > but a global variable for this seems just dangerous. > > Okay, I'll do that instead.
Does this look better? -- Alvaro Herrera http://www.CommandPrompt.com/ The PostgreSQL Company - Command Prompt, Inc.
Index: src/backend/commands/vacuum.c =================================================================== RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/commands/vacuum.c,v retrieving revision 1.364 diff -c -p -r1.364 vacuum.c *** src/backend/commands/vacuum.c 11 Feb 2008 19:14:30 -0000 1.364 --- src/backend/commands/vacuum.c 14 Mar 2008 16:26:08 -0000 *************** static BufferAccessStrategy vac_strategy *** 208,214 **** static List *get_rel_oids(List *relids, const RangeVar *vacrel, const char *stmttype); static void vac_truncate_clog(TransactionId frozenXID); ! static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind); static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt); static void scan_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages); --- 208,215 ---- static List *get_rel_oids(List *relids, const RangeVar *vacrel, const char *stmttype); static void vac_truncate_clog(TransactionId frozenXID); ! static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind, ! bool for_wraparound); static void full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt); static void scan_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages, VacPageList fraged_pages); *************** static Size PageGetFreeSpaceWithFillFact *** 262,267 **** --- 263,271 ---- * relation OIDs to be processed, and vacstmt->relation is ignored. * (The non-NIL case is currently only used by autovacuum.) * + * for_wraparound is used by autovacuum to let us know when it's forcing + * a vacuum for wraparound, which should not be auto-cancelled. + * * bstrategy is normally given as NULL, but in autovacuum it can be passed * in to use the same buffer strategy object across multiple vacuum() calls. * *************** static Size PageGetFreeSpaceWithFillFact *** 273,279 **** */ void vacuum(VacuumStmt *vacstmt, List *relids, ! BufferAccessStrategy bstrategy, bool isTopLevel) { const char *stmttype = vacstmt->vacuum ? "VACUUM" : "ANALYZE"; volatile MemoryContext anl_context = NULL; --- 277,283 ---- */ void vacuum(VacuumStmt *vacstmt, List *relids, ! BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel) { const char *stmttype = vacstmt->vacuum ? "VACUUM" : "ANALYZE"; volatile MemoryContext anl_context = NULL; *************** vacuum(VacuumStmt *vacstmt, List *relids *** 420,426 **** Oid relid = lfirst_oid(cur); if (vacstmt->vacuum) ! vacuum_rel(relid, vacstmt, RELKIND_RELATION); if (vacstmt->analyze) { --- 424,430 ---- Oid relid = lfirst_oid(cur); if (vacstmt->vacuum) ! vacuum_rel(relid, vacstmt, RELKIND_RELATION, for_wraparound); if (vacstmt->analyze) { *************** vac_truncate_clog(TransactionId frozenXI *** 965,971 **** * At entry and exit, we are not inside a transaction. */ static void ! vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind) { LOCKMODE lmode; Relation onerel; --- 969,976 ---- * At entry and exit, we are not inside a transaction. */ static void ! vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind, ! bool for_wraparound) { LOCKMODE lmode; Relation onerel; *************** vacuum_rel(Oid relid, VacuumStmt *vacstm *** 998,1003 **** --- 1003,1012 ---- * contents of other tables is arguably broken, but we won't break it * here by violating transaction semantics.) * + * We also set the VACUUM_FOR_WRAPAROUND flag, which is passed down + * by autovacuum; it's used to avoid cancelling a vacuum that was + * invoked in an emergency. + * * Note: this flag remains set until CommitTransaction or * AbortTransaction. We don't want to clear it until we reset * MyProc->xid/xmin, else OldestXmin might appear to go backwards, *************** vacuum_rel(Oid relid, VacuumStmt *vacstm *** 1005,1010 **** --- 1014,1021 ---- */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); MyProc->vacuumFlags |= PROC_IN_VACUUM; + if (for_wraparound) + MyProc->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND; LWLockRelease(ProcArrayLock); } *************** vacuum_rel(Oid relid, VacuumStmt *vacstm *** 1137,1143 **** * totally unimportant for toast relations. */ if (toast_relid != InvalidOid) ! vacuum_rel(toast_relid, vacstmt, RELKIND_TOASTVALUE); /* * Now release the session-level lock on the master table. --- 1148,1154 ---- * totally unimportant for toast relations. */ if (toast_relid != InvalidOid) ! vacuum_rel(toast_relid, vacstmt, RELKIND_TOASTVALUE, for_wraparound); /* * Now release the session-level lock on the master table. Index: src/backend/postmaster/autovacuum.c =================================================================== RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/postmaster/autovacuum.c,v retrieving revision 1.71.2.1 diff -c -p -r1.71.2.1 autovacuum.c *** src/backend/postmaster/autovacuum.c 20 Feb 2008 16:48:12 -0000 1.71.2.1 --- src/backend/postmaster/autovacuum.c 14 Mar 2008 16:12:36 -0000 *************** static void relation_needs_vacanalyze(Oi *** 285,290 **** --- 285,291 ---- static void autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze, int freeze_min_age, + bool for_wraparound, BufferAccessStrategy bstrategy); static HeapTuple get_pg_autovacuum_tuple_relid(Relation avRel, Oid relid); static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared, *************** do_autovacuum(void) *** 2095,2108 **** /* clean up memory before each iteration */ MemoryContextResetAndDeleteChildren(PortalContext); - /* set the "vacuum for wraparound" flag in PGPROC */ - if (tab->at_wraparound) - { - LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); - MyProc->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND; - LWLockRelease(ProcArrayLock); - } - /* * Save the relation name for a possible error message, to avoid a * catalog lookup in case of an error. Note: they must live in a --- 2096,2101 ---- *************** do_autovacuum(void) *** 2126,2131 **** --- 2119,2125 ---- tab->at_dovacuum, tab->at_doanalyze, tab->at_freeze_min_age, + tab->at_wraparound, bstrategy); /* *************** relation_needs_vacanalyze(Oid relid, *** 2604,2610 **** */ static void autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze, ! int freeze_min_age, BufferAccessStrategy bstrategy) { VacuumStmt vacstmt; --- 2598,2604 ---- */ static void autovacuum_do_vac_analyze(Oid relid, bool dovacuum, bool doanalyze, ! int freeze_min_age, bool for_wraparound, BufferAccessStrategy bstrategy) { VacuumStmt vacstmt; *************** autovacuum_do_vac_analyze(Oid relid, boo *** 2631,2637 **** /* Let pgstat know what we're doing */ autovac_report_activity(&vacstmt, relid); ! vacuum(&vacstmt, list_make1_oid(relid), bstrategy, true); MemoryContextSwitchTo(old_cxt); } --- 2625,2631 ---- /* Let pgstat know what we're doing */ autovac_report_activity(&vacstmt, relid); ! vacuum(&vacstmt, list_make1_oid(relid), bstrategy, for_wraparound, true); MemoryContextSwitchTo(old_cxt); } Index: src/backend/tcop/utility.c =================================================================== RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/tcop/utility.c,v retrieving revision 1.289 diff -c -p -r1.289 utility.c *** src/backend/tcop/utility.c 1 Jan 2008 19:45:52 -0000 1.289 --- src/backend/tcop/utility.c 14 Mar 2008 16:13:21 -0000 *************** ProcessUtility(Node *parsetree, *** 1032,1038 **** break; case T_VacuumStmt: ! vacuum((VacuumStmt *) parsetree, NIL, NULL, isTopLevel); break; case T_ExplainStmt: --- 1032,1038 ---- break; case T_VacuumStmt: ! vacuum((VacuumStmt *) parsetree, NIL, NULL, false, isTopLevel); break; case T_ExplainStmt: Index: src/include/commands/vacuum.h =================================================================== RCS file: /home/alvherre/Code/cvs/pgsql/src/include/commands/vacuum.h,v retrieving revision 1.75 diff -c -p -r1.75 vacuum.h *** src/include/commands/vacuum.h 1 Jan 2008 19:45:57 -0000 1.75 --- src/include/commands/vacuum.h 14 Mar 2008 16:13:40 -0000 *************** extern int vacuum_freeze_min_age; *** 114,120 **** /* in commands/vacuum.c */ extern void vacuum(VacuumStmt *vacstmt, List *relids, ! BufferAccessStrategy bstrategy, bool isTopLevel); extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, int *nindexes, Relation **Irel); extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); --- 114,120 ---- /* in commands/vacuum.c */ extern void vacuum(VacuumStmt *vacstmt, List *relids, ! BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel); extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, int *nindexes, Relation **Irel); extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers