1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

During VACUUM FULL, truncate off any deletable pages that are at the

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.
This commit is contained in:
Tom Lane
2003-02-24 00:57:17 +00:00
parent 3981f2195f
commit 0797bb5c50
7 changed files with 79 additions and 30 deletions

View 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);