The attached patch allows VACUUMS's on small relations to clean up dead
tuples while VACUUM or ANALYSE is running for a long time on some big
table.

This is done by adding a "bool inVacuum" to PGPROC and then making use
of it in GetOldestXmin.

This patch is against current CVS head, but should also apply to 8.0.2
with minorpach  warnings.

-- 
Hannu Krosing <[EMAIL PROTECTED]>
Index: src/backend/access/transam/xact.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xact.c,v
retrieving revision 1.200
diff -c -r1.200 xact.c
*** src/backend/access/transam/xact.c	28 Apr 2005 21:47:10 -0000	1.200
--- src/backend/access/transam/xact.c	17 May 2005 22:06:34 -0000
***************
*** 1411,1416 ****
--- 1411,1424 ----
  	AfterTriggerBeginXact();
  
  	/*
+ 	 * mark the transaction as not VACUUM  (vacuum_rel will set isVacuum to true 
+ 	 * directly after calling BeginTransactionCommand() )
+ 	 */
+ 	if (MyProc != NULL)  
+ 	{
+ 		MyProc->inVacuum = false;
+ 	}
+ 	/*
  	 * done with start processing, set current transaction state to "in
  	 * progress"
  	 */
Index: src/backend/commands/vacuum.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/vacuum.c,v
retrieving revision 1.308
diff -c -r1.308 vacuum.c
*** src/backend/commands/vacuum.c	6 May 2005 17:24:53 -0000	1.308
--- src/backend/commands/vacuum.c	17 May 2005 22:06:35 -0000
***************
*** 36,41 ****
--- 36,42 ----
  #include "executor/executor.h"
  #include "miscadmin.h"
  #include "storage/freespace.h"
+ #include "storage/proc.h"
  #include "storage/sinval.h"
  #include "storage/smgr.h"
  #include "tcop/pquery.h"
***************
*** 343,350 ****
  	 * would be problematic.)
  	 *
  	 * For ANALYZE (no VACUUM): if inside a transaction block, we cannot
! 	 * start/commit our own transactions.  Also, there's no need to do so
! 	 * if only processing one relation.  For multiple relations when not
  	 * within a transaction block, use own transactions so we can release
  	 * locks sooner.
  	 */
--- 344,350 ----
  	 * would be problematic.)
  	 *
  	 * For ANALYZE (no VACUUM): if inside a transaction block, we cannot
! 	 * start/commit our own transactions. For multiple relations when not
  	 * within a transaction block, use own transactions so we can release
  	 * locks sooner.
  	 */
***************
*** 355,364 ****
  		Assert(vacstmt->analyze);
  		if (in_outer_xact)
  			use_own_xacts = false;
- 		else if (list_length(relations) > 1)
- 			use_own_xacts = true;
  		else
! 			use_own_xacts = false;
  	}
  
  	/*
--- 355,362 ----
  		Assert(vacstmt->analyze);
  		if (in_outer_xact)
  			use_own_xacts = false;
  		else
! 			use_own_xacts = true;
  	}
  
  	/*
***************
*** 420,425 ****
--- 418,428 ----
  				if (use_own_xacts)
  				{
  					StartTransactionCommand();
+ 					if (MyProc != NULL)  /* is this needed here ? */
+ 					{
+ 						/* so other vacuums don't look at our xid/xmin in GetOldestXmin() */
+ 						MyProc->inVacuum = true;
+ 					}
  					/* functions in indexes may want a snapshot set */
  					ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
  				}
***************
*** 905,910 ****
--- 908,920 ----
  
  	/* Begin a transaction for vacuuming this relation */
  	StartTransactionCommand();
+ 	
+ 	if (MyProc != NULL)  /* is this needed here ? */
+ 	{
+ 		/* so other vacuums don't look at our xid/xmin in GetOldestXmin() */
+ 		MyProc->inVacuum = true;
+ 	}
+ 	
  	/* functions in indexes may want a snapshot set */
  	ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
  
Index: src/backend/storage/ipc/sinval.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v
retrieving revision 1.75
diff -c -r1.75 sinval.c
*** src/backend/storage/ipc/sinval.c	31 Dec 2004 22:00:56 -0000	1.75
--- src/backend/storage/ipc/sinval.c	17 May 2005 22:06:36 -0000
***************
*** 697,703 ****
  		{
  			PGPROC	   *proc = (PGPROC *) MAKE_PTR(pOffset);
  
! 			if (allDbs || proc->databaseId == MyDatabaseId)
  			{
  				/* Fetch xid just once - see GetNewTransactionId */
  				TransactionId xid = proc->xid;
--- 697,703 ----
  		{
  			PGPROC	   *proc = (PGPROC *) MAKE_PTR(pOffset);
  
! 			if ((proc->inVacuum == false) && (allDbs || proc->databaseId == MyDatabaseId))
  			{
  				/* Fetch xid just once - see GetNewTransactionId */
  				TransactionId xid = proc->xid;
***************
*** 845,854 ****
  			 * them as running anyway.	We also assume that such xacts
  			 * can't compute an xmin older than ours, so they needn't be
  			 * considered in computing globalxmin.
  			 */
  			if (proc == MyProc ||
  				!TransactionIdIsNormal(xid) ||
! 				TransactionIdFollowsOrEquals(xid, xmax))
  				continue;
  
  			if (TransactionIdPrecedes(xid, xmin))
--- 845,858 ----
  			 * them as running anyway.	We also assume that such xacts
  			 * can't compute an xmin older than ours, so they needn't be
  			 * considered in computing globalxmin.
+ 			 *
+ 			 * there is also no need to consider transaxtions runnibg the 
+ 			 * vacuum command as it will not affect tuple visibility
  			 */
  			if (proc == MyProc ||
  				!TransactionIdIsNormal(xid) ||
! 				TransactionIdFollowsOrEquals(xid, xmax) ||
! 				proc->inVacuum == true )
  				continue;
  
  			if (TransactionIdPrecedes(xid, xmin))
Index: src/include/storage/proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/storage/proc.h,v
retrieving revision 1.77
diff -c -r1.77 proc.h
*** src/include/storage/proc.h	31 Dec 2004 22:03:42 -0000	1.77
--- src/include/storage/proc.h	17 May 2005 22:06:36 -0000
***************
*** 63,68 ****
--- 63,73 ----
  								 * were starting our xact: vacuum must not
  								 * remove tuples deleted by xid >= xmin ! */
  
+ 	bool		inVacuum;		/* true if current command is vacuum.
+ 								 * xid or xmin of other vacuum commands 
+ 								 * need not be used when 
+ 								 * finding global xmin for removing tuples */
+ 
  	int			pid;			/* This backend's process id */
  	Oid			databaseId;		/* OID of database this backend is using */
  
---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Reply via email to