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 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -125,7 +125,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
if (chldtuple.ituplen > 1) if (chldtuple.ituplen > 1)
{ {
/* /*
* child was splitted, so we need mark completion * child was split, so we need mark completion
* insert(split) * insert(split)
*/ */
int j; int j;
...@@ -329,9 +329,9 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion) ...@@ -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, * 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 * tries to get smaller index
*/ */
...@@ -505,10 +505,15 @@ gistbulkdelete(PG_FUNCTION_ARGS) ...@@ -505,10 +505,15 @@ gistbulkdelete(PG_FUNCTION_ARGS)
*ptr; *ptr;
bool needLock; bool needLock;
if (callback_state)
{
stack = (GistBDItem *) palloc0(sizeof(GistBDItem)); stack = (GistBDItem *) palloc0(sizeof(GistBDItem));
stack->blkno = GIST_ROOT_BLKNO; stack->blkno = GIST_ROOT_BLKNO;
needFullVacuum = false; needFullVacuum = false;
}
else
stack = NULL;
while (stack) while (stack)
{ {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* This file contains only the public interface routines. * This file contains only the public interface routines.
...@@ -496,6 +496,17 @@ hashbulkdelete(PG_FUNCTION_ARGS) ...@@ -496,6 +496,17 @@ hashbulkdelete(PG_FUNCTION_ARGS)
tuples_removed = 0; tuples_removed = 0;
num_index_tuples = 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 * 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 * keep a copy of the last-seen metapage so that we can use its
...@@ -644,11 +655,6 @@ loop_top: ...@@ -644,11 +655,6 @@ loop_top:
_hash_wrtbuf(rel, metabuf); _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->num_index_tuples = num_index_tuples;
result->tuples_removed = tuples_removed; result->tuples_removed = tuples_removed;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
* index_open - open an index relation by relation OID * index_open - open an index relation by relation OID
...@@ -685,6 +685,11 @@ index_getmulti(IndexScanDesc scan, ...@@ -685,6 +685,11 @@ index_getmulti(IndexScanDesc scan,
* callback routine tells whether a given main-heap tuple is * callback routine tells whether a given main-heap tuple is
* to be deleted * 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 * return value is an optional palloc'd struct of statistics
* ---------------- * ----------------
*/ */
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -543,8 +543,9 @@ btbulkdelete(PG_FUNCTION_ARGS)
double num_index_tuples; double num_index_tuples;
OffsetNumber deletable[MaxOffsetNumber]; OffsetNumber deletable[MaxOffsetNumber];
int ndeletable; int ndeletable;
Buffer buf; Buffer buf = NULL;
BlockNumber num_pages; BlockNumber num_pages;
bool scanindex = true;
tuples_removed = 0; tuples_removed = 0;
num_index_tuples = 0; num_index_tuples = 0;
...@@ -565,8 +566,15 @@ btbulkdelete(PG_FUNCTION_ARGS) ...@@ -565,8 +566,15 @@ btbulkdelete(PG_FUNCTION_ARGS)
* skip obtaining exclusive lock on empty pages though, since no indexscan * skip obtaining exclusive lock on empty pages though, since no indexscan
* could be stopped on those. * could be stopped on those.
*/ */
if (callback_state)
{
buf = _bt_get_endpoint(rel, 0, false); buf = _bt_get_endpoint(rel, 0, false);
if (BufferIsValid(buf)) /* check for empty index */ scanindex = BufferIsValid(buf); /* check for empty index */
}
else
scanindex = false;
if (scanindex)
{ {
for (;;) for (;;)
{ {
...@@ -649,7 +657,10 @@ btbulkdelete(PG_FUNCTION_ARGS) ...@@ -649,7 +657,10 @@ btbulkdelete(PG_FUNCTION_ARGS)
result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
result->num_pages = num_pages; result->num_pages = num_pages;
if (scanindex)
result->num_index_tuples = num_index_tuples; result->num_index_tuples = num_index_tuples;
else
result->num_index_tuples = -1;
result->tuples_removed = tuples_removed; result->tuples_removed = tuples_removed;
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * 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,6 +719,7 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples, ...@@ -719,6 +719,7 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
/* overwrite the existing statistics in the tuple */ /* overwrite the existing statistics in the tuple */
pgcform = (Form_pg_class) GETSTRUCT(&rtup); pgcform = (Form_pg_class) GETSTRUCT(&rtup);
pgcform->relpages = (int32) num_pages; pgcform->relpages = (int32) num_pages;
if (num_tuples >= 0 )
pgcform->reltuples = (float4) num_tuples; pgcform->reltuples = (float4) num_tuples;
pgcform->relhasindex = hasindex; pgcform->relhasindex = hasindex;
...@@ -2961,15 +2962,18 @@ scan_index(Relation indrel, double num_tuples) ...@@ -2961,15 +2962,18 @@ scan_index(Relation indrel, double num_tuples)
if (!stats) if (!stats)
return; 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), vac_update_relstats(RelationGetRelid(indrel),
stats->num_pages, stats->num_index_tuples, stats->num_pages, num_tuples,
false); false);
ereport(elevel, ereport(elevel,
(errmsg("index \"%s\" now contains %.0f row versions in %u pages", (errmsg("index \"%s\" now contains %.0f row versions in %u pages",
RelationGetRelationName(indrel), RelationGetRelationName(indrel),
stats->num_index_tuples, num_tuples,
stats->num_pages), stats->num_pages),
errdetail("%u index pages have been deleted, %u are currently reusable.\n" errdetail("%u index pages have been deleted, %u are currently reusable.\n"
"%s.", "%s.",
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -639,16 +639,19 @@ lazy_scan_index(Relation indrel, LVRelStats *vacrelstats)
if (!stats) if (!stats)
return; 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), vac_update_relstats(RelationGetRelid(indrel),
stats->num_pages, stats->num_pages,
stats->num_index_tuples, vacrelstats->rel_tuples,
false); false);
ereport(elevel, ereport(elevel,
(errmsg("index \"%s\" now contains %.0f row versions in %u pages", (errmsg("index \"%s\" now contains %.0f row versions in %u pages",
RelationGetRelationName(indrel), RelationGetRelationName(indrel),
stats->num_index_tuples, vacrelstats->rel_tuples,
stats->num_pages), stats->num_pages),
errdetail("%u index pages have been deleted, %u are currently reusable.\n" errdetail("%u index pages have been deleted, %u are currently reusable.\n"
"%s.", "%s.",
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -38,6 +38,8 @@ typedef struct IndexBulkDeleteResult
BlockNumber num_pages; /* pages remaining in index */ BlockNumber num_pages; /* pages remaining in index */
BlockNumber pages_removed; /* # removed by bulk-delete operation */ BlockNumber pages_removed; /* # removed by bulk-delete operation */
double num_index_tuples; /* tuples remaining */ 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 */ double tuples_removed; /* # removed by bulk-delete operation */
BlockNumber pages_deleted; /* # unused pages in index */ BlockNumber pages_deleted; /* # unused pages in index */
BlockNumber pages_free; /* # pages available for reuse */ 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