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

Reply via email to