]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
During VACUUM FULL, truncate off any deletable pages that are at the
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 24 Feb 2003 00:57:17 +0000 (00:57 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 24 Feb 2003 00:57:17 +0000 (00:57 +0000)
end of a btree index.  This isn't super-effective, since we won't move
nondeletable pages, but it's better than nothing.  Also, improve stats
displayed during VACUUM VERBOSE.

src/backend/access/gist/gist.c
src/backend/access/hash/hash.c
src/backend/access/nbtree/nbtree.c
src/backend/access/rtree/rtree.c
src/backend/commands/vacuum.c
src/backend/commands/vacuumlazy.c
src/include/access/genam.h

index 472bcf4527661ad4580dda0bf51f405cae946ba9..56a5c6fb603f94b579ce749b77a9db37549c3d4c 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.100 2003/02/22 00:45:03 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.101 2003/02/24 00:57:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1648,11 +1648,10 @@ gistbulkdelete(PG_FUNCTION_ARGS)
        /* return statistics */
        num_pages = RelationGetNumberOfBlocks(rel);
 
-       result = (IndexBulkDeleteResult *) palloc(sizeof(IndexBulkDeleteResult));
+       result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
        result->num_pages = num_pages;
        result->num_index_tuples = num_index_tuples;
        result->tuples_removed = tuples_removed;
-       result->pages_free = 0;
 
        PG_RETURN_POINTER(result);
 }
index 0ec2380cef0fa0ef23d011d9e1a1fb8af0aaad14..705041f7d274e8e6ae4e6708d252b81763ae70d6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.61 2003/02/22 00:45:03 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.62 2003/02/24 00:57:17 tgl Exp $
  *
  * NOTES
  *       This file contains only the public interface routines.
@@ -489,11 +489,10 @@ hashbulkdelete(PG_FUNCTION_ARGS)
        /* return statistics */
        num_pages = RelationGetNumberOfBlocks(rel);
 
-       result = (IndexBulkDeleteResult *) palloc(sizeof(IndexBulkDeleteResult));
+       result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
        result->num_pages = num_pages;
        result->num_index_tuples = num_index_tuples;
        result->tuples_removed = tuples_removed;
-       result->pages_free = 0;
 
        PG_RETURN_POINTER(result);
 }
index 343fa082d664a832a17c03fdf16ccb0b13c409f8..c393e907b5927a02bf71cee5549e9bf4b4fc1a88 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.99 2003/02/23 23:27:21 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.100 2003/02/24 00:57:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,6 +24,7 @@
 #include "catalog/index.h"
 #include "miscadmin.h"
 #include "storage/freespace.h"
+#include "storage/smgr.h"
 
 
 /* Working state for btbuild and its callback */
@@ -673,11 +674,10 @@ btbulkdelete(PG_FUNCTION_ARGS)
        /* return statistics */
        num_pages = RelationGetNumberOfBlocks(rel);
 
-       result = (IndexBulkDeleteResult *) palloc(sizeof(IndexBulkDeleteResult));
+       result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
        result->num_pages = num_pages;
        result->num_index_tuples = num_index_tuples;
        result->tuples_removed = tuples_removed;
-       result->pages_free = 0;         /* not computed here */
 
        PG_RETURN_POINTER(result);
 }
@@ -746,6 +746,12 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
                                pageSpaces[nFreePages].avail = BLCKSZ-1;
                                nFreePages++;
                        }
+                       pages_deleted++;
+               }
+               else if (P_ISDELETED(opaque))
+               {
+                       /* Already deleted, but can't recycle yet */
+                       pages_deleted++;
                }
                else if ((opaque->btpo_flags & BTP_HALF_DEAD) ||
                                 P_FIRSTDATAKEY(opaque) > PageGetMaxOffsetNumber(page))
@@ -758,7 +764,10 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
                        oldcontext = MemoryContextSwitchTo(mycontext);
 
                        ndel = _bt_pagedel(rel, buf, info->vacuum_full);
-                       pages_deleted += ndel;
+
+                       /* count only this page, else may double-count parent */
+                       if (ndel)
+                               pages_deleted++;
 
                        /*
                         * During VACUUM FULL it's okay to recycle deleted pages
@@ -786,6 +795,50 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
                _bt_relbuf(rel, buf);
        }
 
+       /*
+        * During VACUUM FULL, we truncate off any recyclable pages at the
+        * end of the index.  In a normal vacuum it'd be unsafe to do this
+        * except by acquiring exclusive lock on the index and then rechecking
+        * all the pages; doesn't seem worth it.
+        */
+       if (info->vacuum_full && nFreePages > 0)
+       {
+               BlockNumber     new_pages = num_pages;
+
+               while (nFreePages > 0 &&
+                          pageSpaces[nFreePages-1].blkno == new_pages-1)
+               {
+                       new_pages--;
+                       pages_deleted--;
+                       nFreePages--;
+               }
+               if (new_pages != num_pages)
+               {
+                       int                     i;
+
+                       /*
+                        * Okay to truncate.
+                        *
+                        * First, flush any shared buffers for the blocks we intend to
+                        * delete.  FlushRelationBuffers is a bit more than we need for
+                        * this, since it will also write out dirty buffers for blocks we
+                        * aren't deleting, but it's the closest thing in bufmgr's API.
+                        */
+                       i = FlushRelationBuffers(rel, new_pages);
+                       if (i < 0)
+                               elog(ERROR, "btvacuumcleanup: FlushRelationBuffers returned %d",
+                                        i);
+
+                       /*
+                        * Do the physical truncation.
+                        */
+                       new_pages = smgrtruncate(DEFAULT_SMGR, rel, new_pages);
+                       rel->rd_nblocks = new_pages; /* update relcache immediately */
+                       rel->rd_targblock = InvalidBlockNumber;
+                       num_pages = new_pages;
+               }
+       }
+
        /*
         * Update the shared Free Space Map with the info we now have about
         * free space in the index, discarding any old info the map may have.
@@ -797,13 +850,9 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
 
        MemoryContextDelete(mycontext);
 
-       if (pages_deleted > 0)
-               elog(info->message_level, "Index %s: %u pages, deleted %u; %u now free",
-                        RelationGetRelationName(rel),
-                        num_pages, pages_deleted, nFreePages);
-
        /* update statistics */
        stats->num_pages = num_pages;
+       stats->pages_deleted = pages_deleted;
        stats->pages_free = nFreePages;
 
        PG_RETURN_POINTER(stats);
index b6b2a19e10b32e190e66f1d282df13a70d44c20f..96bdd5ba1abb035e5ce4d2bb555115c6abf579d0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.76 2003/02/22 00:45:04 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.77 2003/02/24 00:57:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1248,11 +1248,10 @@ rtbulkdelete(PG_FUNCTION_ARGS)
        /* return statistics */
        num_pages = RelationGetNumberOfBlocks(rel);
 
-       result = (IndexBulkDeleteResult *) palloc(sizeof(IndexBulkDeleteResult));
+       result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
        result->num_pages = num_pages;
        result->num_index_tuples = num_index_tuples;
        result->tuples_removed = tuples_removed;
-       result->pages_free = 0;
 
        PG_RETURN_POINTER(result);
 }
index ad79d0923ebef8d36a3003f264eb758fc7f44070..8b8cff6d30e4be5d40bf5a541a047739e22ca772 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.249 2003/02/23 20:32:12 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.250 2003/02/24 00:57:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2626,9 +2626,10 @@ scan_index(Relation indrel, double num_tuples)
                                                stats->num_pages, stats->num_index_tuples,
                                                false);
 
-       elog(elevel, "Index %s: Pages %u, %u free; Tuples %.0f.\n\t%s",
+       elog(elevel, "Index %s: Pages %u, %u deleted, %u free; Tuples %.0f.\n\t%s",
                 RelationGetRelationName(indrel),
-                stats->num_pages, stats->pages_free, stats->num_index_tuples,
+                stats->num_pages, stats->pages_deleted, stats->pages_free,
+                stats->num_index_tuples,
                 vac_show_rusage(&ru0));
 
        /*
@@ -2687,9 +2688,9 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
                                                stats->num_pages, stats->num_index_tuples,
                                                false);
 
-       elog(elevel, "Index %s: Pages %u, %u free; Tuples %.0f: Deleted %.0f.\n\t%s",
+       elog(elevel, "Index %s: Pages %u, %u deleted, %u free; Tuples %.0f: Deleted %.0f.\n\t%s",
                 RelationGetRelationName(indrel),
-                stats->num_pages, stats->pages_free,
+                stats->num_pages, stats->pages_deleted, stats->pages_free,
                 stats->num_index_tuples - keep_tuples, stats->tuples_removed,
                 vac_show_rusage(&ru0));
 
index 00bd905addfc94ee97b76ae56722803b933307d3..6eee5765e72f5493713f4e6e0c5e894bc847c7ae 100644 (file)
@@ -31,7 +31,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.25 2003/02/23 20:32:12 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.26 2003/02/24 00:57:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -586,9 +586,10 @@ lazy_scan_index(Relation indrel, LVRelStats *vacrelstats)
                                                stats->num_pages, stats->num_index_tuples,
                                                false);
 
-       elog(elevel, "Index %s: Pages %u, %u free; Tuples %.0f.\n\t%s",
+       elog(elevel, "Index %s: Pages %u, %u deleted, %u free; Tuples %.0f.\n\t%s",
                 RelationGetRelationName(indrel),
-                stats->num_pages, stats->pages_free, stats->num_index_tuples,
+                stats->num_pages, stats->pages_deleted, stats->pages_free,
+                stats->num_index_tuples,
                 vac_show_rusage(&ru0));
 
        pfree(stats);
@@ -641,9 +642,9 @@ lazy_vacuum_index(Relation indrel, LVRelStats *vacrelstats)
                                                stats->num_pages, stats->num_index_tuples,
                                                false);
 
-       elog(elevel, "Index %s: Pages %u, %u free; Tuples %.0f: Deleted %.0f.\n\t%s",
+       elog(elevel, "Index %s: Pages %u, %u deleted, %u free; Tuples %.0f: Deleted %.0f.\n\t%s",
                 RelationGetRelationName(indrel),
-                stats->num_pages, stats->pages_free,
+                stats->num_pages, stats->pages_deleted, stats->pages_free,
                 stats->num_index_tuples, stats->tuples_removed,
                 vac_show_rusage(&ru0));
 
index 59ecf1d8f4f6fe1e917b71c43c642f1881d1ec3a..e018bb8007ec726bf24e0caa7a4ceb2f3ea704b5 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: genam.h,v 1.38 2003/02/22 00:45:05 tgl Exp $
+ * $Id: genam.h,v 1.39 2003/02/24 00:57:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,7 +34,8 @@ typedef struct IndexBulkDeleteResult
        BlockNumber num_pages;          /* pages remaining in index */
        double          num_index_tuples;               /* tuples remaining */
        double          tuples_removed; /* # removed by bulk-delete operation */
-       BlockNumber     pages_free;             /* # unused pages in index */
+       BlockNumber     pages_deleted;  /* # unused pages in index */
+       BlockNumber     pages_free;             /* # pages available for reuse */
 } IndexBulkDeleteResult;
 
 /* Typedef for callback function to determine if a tuple is bulk-deletable */