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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers