Commit bf324946 authored by Bruce Momjian's avatar Bruce Momjian

Allow VACUUM to complete faster by avoiding scanning the indexes when no

rows were removed from the heap by the VACUUM.

Simon Riggs
parent 85d8ee84
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.11 2005/11/22 18:17:05 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.12 2006/02/11 16:59:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -125,7 +125,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
if (chldtuple.ituplen > 1)
{
/*
* child was splitted, so we need mark completion
* child was split, so we need mark completion
* insert(split)
*/
int j;
......@@ -329,9 +329,9 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
}
/*
* For usial vacuum just update FSM, for full vacuum
* For usual vacuum just update FSM, for full vacuum
* reforms parent tuples if some of childs was deleted or changed,
* update invalid tuples (they can exsist from last crash recovery only),
* update invalid tuples (they can exist from last crash recovery only),
* tries to get smaller index
*/
......@@ -505,10 +505,15 @@ gistbulkdelete(PG_FUNCTION_ARGS)
*ptr;
bool needLock;
stack = (GistBDItem *) palloc0(sizeof(GistBDItem));
if (callback_state)
{
stack = (GistBDItem *) palloc0(sizeof(GistBDItem));
stack->blkno = GIST_ROOT_BLKNO;
needFullVacuum = false;
stack->blkno = GIST_ROOT_BLKNO;
needFullVacuum = false;
}
else
stack = NULL;
while (stack)
{
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.83 2006/01/25 23:26:11 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.84 2006/02/11 16:59:09 momjian Exp $
*
* NOTES
* This file contains only the public interface routines.
......@@ -496,6 +496,17 @@ hashbulkdelete(PG_FUNCTION_ARGS)
tuples_removed = 0;
num_index_tuples = 0;
/* return statistics */
num_pages = RelationGetNumberOfBlocks(rel);
result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
result->num_pages = num_pages;
if (!callback_state)
{
PG_RETURN_POINTER(result);
}
/*
* Read the metapage to fetch original bucket and tuple counts. Also, we
* keep a copy of the last-seen metapage so that we can use its
......@@ -644,11 +655,6 @@ loop_top:
_hash_wrtbuf(rel, metabuf);
/* return statistics */
num_pages = RelationGetNumberOfBlocks(rel);
result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
result->num_pages = num_pages;
result->num_index_tuples = num_index_tuples;
result->tuples_removed = tuples_removed;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.87 2005/12/03 05:51:00 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.88 2006/02/11 16:59:09 momjian Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relation OID
......@@ -685,6 +685,11 @@ index_getmulti(IndexScanDesc scan,
* callback routine tells whether a given main-heap tuple is
* to be deleted
*
* passing NULL callback_state can be interpreted by the
* index access method as meaning that the index does not need
* to be scanned in logical sequence to remove rows for this call
* index_vacuum_cleanup is always required after this, however.
*
* return value is an optional palloc'd struct of statistics
* ----------------
*/
......
......@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.136 2006/01/25 23:04:20 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.137 2006/02/11 16:59:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -543,8 +543,9 @@ btbulkdelete(PG_FUNCTION_ARGS)
double num_index_tuples;
OffsetNumber deletable[MaxOffsetNumber];
int ndeletable;
Buffer buf;
Buffer buf = NULL;
BlockNumber num_pages;
bool scanindex = true;
tuples_removed = 0;
num_index_tuples = 0;
......@@ -565,8 +566,15 @@ btbulkdelete(PG_FUNCTION_ARGS)
* skip obtaining exclusive lock on empty pages though, since no indexscan
* could be stopped on those.
*/
buf = _bt_get_endpoint(rel, 0, false);
if (BufferIsValid(buf)) /* check for empty index */
if (callback_state)
{
buf = _bt_get_endpoint(rel, 0, false);
scanindex = BufferIsValid(buf); /* check for empty index */
}
else
scanindex = false;
if (scanindex)
{
for (;;)
{
......@@ -649,7 +657,10 @@ btbulkdelete(PG_FUNCTION_ARGS)
result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
result->num_pages = num_pages;
result->num_index_tuples = num_index_tuples;
if (scanindex)
result->num_index_tuples = num_index_tuples;
else
result->num_index_tuples = -1;
result->tuples_removed = tuples_removed;
PG_RETURN_POINTER(result);
......
......@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.321 2006/01/18 20:35:05 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.322 2006/02/11 16:59:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -719,7 +719,8 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
/* overwrite the existing statistics in the tuple */
pgcform = (Form_pg_class) GETSTRUCT(&rtup);
pgcform->relpages = (int32) num_pages;
pgcform->reltuples = (float4) num_tuples;
if (num_tuples >= 0 )
pgcform->reltuples = (float4) num_tuples;
pgcform->relhasindex = hasindex;
/*
......@@ -2961,15 +2962,18 @@ scan_index(Relation indrel, double num_tuples)
if (!stats)
return;
/* now update statistics in pg_class */
/* now update statistics in pg_class
* we use the number of tuples from the table because we have not
* actually scanned the index, so don't know the number of tuples in index
*/
vac_update_relstats(RelationGetRelid(indrel),
stats->num_pages, stats->num_index_tuples,
stats->num_pages, num_tuples,
false);
ereport(elevel,
(errmsg("index \"%s\" now contains %.0f row versions in %u pages",
RelationGetRelationName(indrel),
stats->num_index_tuples,
num_tuples,
stats->num_pages),
errdetail("%u index pages have been deleted, %u are currently reusable.\n"
"%s.",
......
......@@ -31,7 +31,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.63 2005/11/22 18:17:09 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.64 2006/02/11 16:59:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -639,16 +639,19 @@ lazy_scan_index(Relation indrel, LVRelStats *vacrelstats)
if (!stats)
return;
/* now update statistics in pg_class */
/* now update statistics in pg_class
* we use the number of tuples from the table because we have not
* actually scanned the index, so don't know the number of tuples in index
*/
vac_update_relstats(RelationGetRelid(indrel),
stats->num_pages,
stats->num_index_tuples,
vacrelstats->rel_tuples,
false);
ereport(elevel,
(errmsg("index \"%s\" now contains %.0f row versions in %u pages",
RelationGetRelationName(indrel),
stats->num_index_tuples,
vacrelstats->rel_tuples,
stats->num_pages),
errdetail("%u index pages have been deleted, %u are currently reusable.\n"
"%s.",
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/genam.h,v 1.54 2005/12/03 05:51:03 tgl Exp $
* $PostgreSQL: pgsql/src/include/access/genam.h,v 1.55 2006/02/11 16:59:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -38,6 +38,8 @@ typedef struct IndexBulkDeleteResult
BlockNumber num_pages; /* pages remaining in index */
BlockNumber pages_removed; /* # removed by bulk-delete operation */
double num_index_tuples; /* tuples remaining */
/* should set to -1 if index not scanned */
/* because no records to delete */
double tuples_removed; /* # removed by bulk-delete operation */
BlockNumber pages_deleted; /* # unused pages in index */
BlockNumber pages_free; /* # pages available for reuse */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment