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