diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 472bcf45276..56a5c6fb603 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -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); } diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 0ec2380cef0..705041f7d27 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -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); } diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 343fa082d66..c393e907b59 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -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); diff --git a/src/backend/access/rtree/rtree.c b/src/backend/access/rtree/rtree.c index b6b2a19e10b..96bdd5ba1ab 100644 --- a/src/backend/access/rtree/rtree.c +++ b/src/backend/access/rtree/rtree.c @@ -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); } diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index ad79d0923eb..8b8cff6d30e 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -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)); diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c index 00bd905addf..6eee5765e72 100644 --- a/src/backend/commands/vacuumlazy.c +++ b/src/backend/commands/vacuumlazy.c @@ -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)); diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 59ecf1d8f4f..e018bb8007e 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -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 */