]> granicus.if.org Git - postgresql/commitdiff
Trivial patch to double vacuum speed on tables with no indexes (prevent
authorBruce Momjian <bruce@momjian.us>
Mon, 4 Sep 2006 21:40:23 +0000 (21:40 +0000)
committerBruce Momjian <bruce@momjian.us>
Mon, 4 Sep 2006 21:40:23 +0000 (21:40 +0000)
second scan of table).

Gregory Stark

src/backend/commands/vacuumlazy.c

index 2202e7b7e9ace65a97d831a791557b9ee7c88d0c..18bea02687bd9a0f314a0fffefe1a32207f7821e 100644 (file)
  * perform a pass of index cleanup and page compaction, then resume the heap
  * scan with an empty TID array.
  *
+ * As a special exception if we're processing a table with no indexes we can
+ * vacuum each page as we go so we don't need to allocate more space than
+ * enough to hold as many heap tuples fit on one page.
+ *
  * We can limit the storage for page free space to MaxFSMPages entries,
  * since that's the most the free space map will be willing to remember
  * anyway.     If the relation has fewer than that many pages with free space,
@@ -31,7 +35,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.76 2006/07/31 20:09:00 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.77 2006/09/04 21:40:23 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -106,7 +110,7 @@ static void lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats,
                                                           TransactionId OldestXmin);
 static BlockNumber count_nondeletable_pages(Relation onerel,
                                                 LVRelStats *vacrelstats, TransactionId OldestXmin);
-static void lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks);
+static void lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks, unsigned nindexes);
 static void lazy_record_dead_tuple(LVRelStats *vacrelstats,
                                           ItemPointer itemptr);
 static void lazy_record_free_space(LVRelStats *vacrelstats,
@@ -206,7 +210,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
  *             This routine sets commit status bits, builds lists of dead tuples
  *             and pages with free space, and calculates statistics on the number
  *             of live tuples in the heap.  When done, or when we run low on space
- *             for dead-tuple TIDs, invoke vacuuming of indexes and heap.
+ *             for dead-tuple TIDs, or after every page if the table has no indexes 
+ *             invoke vacuuming of indexes and heap.
  *
  *             It also updates the minimum Xid found anywhere on the table in
  *             vacrelstats->minxid, for later storing it in pg_class.relminxid.
@@ -247,7 +252,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
        vacrelstats->rel_pages = nblocks;
        vacrelstats->nonempty_pages = 0;
 
-       lazy_space_alloc(vacrelstats, nblocks);
+       lazy_space_alloc(vacrelstats, nblocks, nindexes);
 
        for (blkno = 0; blkno < nblocks; blkno++)
        {
@@ -282,8 +287,14 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
 
                buf = ReadBuffer(onerel, blkno);
 
-               /* In this phase we only need shared access to the buffer */
-               LockBuffer(buf, BUFFER_LOCK_SHARE);
+               /* In this phase we only need shared access to the buffer unless we're
+                * going to do the vacuuming now which we do if there are no indexes 
+                */
+
+               if (nindexes)
+                       LockBuffer(buf, BUFFER_LOCK_SHARE);
+               else
+                       LockBufferForCleanup(buf);
 
                page = BufferGetPage(buf);
 
@@ -450,6 +461,12 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
                {
                        lazy_record_free_space(vacrelstats, blkno,
                                                                   PageGetFreeSpace(page));
+               } else if (!nindexes) {
+                       /* If there are no indexes we can vacuum the page right now instead
+                        * of doing a second scan */
+                       lazy_vacuum_page(onerel, blkno, buf, 0, vacrelstats);
+                       lazy_record_free_space(vacrelstats, blkno, PageGetFreeSpace(BufferGetPage(buf)));
+                       vacrelstats->num_dead_tuples = 0;
                }
 
                /* Remember the location of the last page with nonremovable tuples */
@@ -891,16 +908,20 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats,
  * See the comments at the head of this file for rationale.
  */
 static void
-lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
+lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks, unsigned nindexes)
 {
        long            maxtuples;
        int                     maxpages;
 
-       maxtuples = (maintenance_work_mem * 1024L) / sizeof(ItemPointerData);
-       maxtuples = Min(maxtuples, INT_MAX);
-       maxtuples = Min(maxtuples, MaxAllocSize / sizeof(ItemPointerData));
-       /* stay sane if small maintenance_work_mem */
-       maxtuples = Max(maxtuples, MaxHeapTuplesPerPage);
+       if (nindexes) {
+               maxtuples = (maintenance_work_mem * 1024L) / sizeof(ItemPointerData);
+               maxtuples = Min(maxtuples, INT_MAX);
+               maxtuples = Min(maxtuples, MaxAllocSize / sizeof(ItemPointerData));
+               /* stay sane if small maintenance_work_mem */
+               maxtuples = Max(maxtuples, MaxHeapTuplesPerPage);
+       } else {
+               maxtuples = MaxHeapTuplesPerPage;
+       }
 
        vacrelstats->num_dead_tuples = 0;
        vacrelstats->max_dead_tuples = (int) maxtuples;