diff options
Diffstat (limited to 'src/backend/access')
-rw-r--r-- | src/backend/access/gin/ginvacuum.c | 33 | ||||
-rw-r--r-- | src/backend/access/gist/gistvacuum.c | 82 | ||||
-rw-r--r-- | src/backend/access/hash/hash.c | 59 | ||||
-rw-r--r-- | src/backend/access/index/indexam.c | 31 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtree.c | 42 |
5 files changed, 123 insertions, 124 deletions
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index ab1861fdaa9..bc8a3e53efc 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gin/ginvacuum.c,v 1.1 2006/05/02 11:28:54 teodor Exp $ + * $PostgreSQL: pgsql/src/backend/access/gin/ginvacuum.c,v 1.2 2006/05/02 22:25:10 tgl Exp $ *------------------------------------------------------------------------- */ @@ -474,17 +474,25 @@ ginVacuumEntryPage(GinVacuumState *gvs, Buffer buffer, BlockNumber *roots, uint3 Datum ginbulkdelete(PG_FUNCTION_ARGS) { - Relation index = (Relation) PG_GETARG_POINTER(0); - IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(1); - void *callback_state = (void *) PG_GETARG_POINTER(2); + IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(1); + IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(2); + void *callback_state = (void *) PG_GETARG_POINTER(3); + Relation index = info->index; BlockNumber blkno = GIN_ROOT_BLKNO; GinVacuumState gvs; Buffer buffer; BlockNumber rootOfPostingTree[ BLCKSZ/ (sizeof(IndexTupleData)+sizeof(ItemId)) ]; uint32 nRoot; + /* first time through? */ + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + /* we'll re-count the tuples each time */ + stats->num_index_tuples = 0; + gvs.index = index; - gvs.result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + gvs.result = stats; gvs.callback = callback; gvs.callback_state = callback_state; initGinState(&gvs.ginstate, index); @@ -564,9 +572,9 @@ ginbulkdelete(PG_FUNCTION_ARGS) { Datum ginvacuumcleanup(PG_FUNCTION_ARGS) { - Relation index = (Relation) PG_GETARG_POINTER(0); - IndexVacuumCleanupInfo *info = (IndexVacuumCleanupInfo *) PG_GETARG_POINTER(1); - IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(2); + IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(1); + Relation index = info->index; bool needLock = !RELATION_IS_LOCAL(index); BlockNumber npages, blkno; @@ -576,6 +584,15 @@ ginvacuumcleanup(PG_FUNCTION_ARGS) { BlockNumber lastBlock = GIN_ROOT_BLKNO, lastFilledBlock = GIN_ROOT_BLKNO; + /* Set up all-zero stats if ginbulkdelete wasn't called */ + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + /* + * XXX we always report the heap tuple count as the number of index + * entries. This is bogus if the index is partial, but it's real hard + * to tell how many distinct heap entries are referenced by a GIN index. + */ + stats->num_index_tuples = info->num_heap_tuples; if (info->vacuum_full) { LockRelation(index, AccessExclusiveLock); diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index 285f1301321..eafd472c5fd 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -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.18 2006/03/31 23:32:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.19 2006/05/02 22:25:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -343,9 +343,9 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion) Datum gistvacuumcleanup(PG_FUNCTION_ARGS) { - Relation rel = (Relation) PG_GETARG_POINTER(0); - IndexVacuumCleanupInfo *info = (IndexVacuumCleanupInfo *) PG_GETARG_POINTER(1); - GistBulkDeleteResult *stats = (GistBulkDeleteResult *) PG_GETARG_POINTER(2); + IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0); + GistBulkDeleteResult *stats = (GistBulkDeleteResult *) PG_GETARG_POINTER(1); + Relation rel = info->index; BlockNumber npages, blkno; BlockNumber nFreePages, @@ -355,6 +355,19 @@ gistvacuumcleanup(PG_FUNCTION_ARGS) lastFilledBlock = GIST_ROOT_BLKNO; bool needLock; + /* Set up all-zero stats if gistbulkdelete wasn't called */ + if (stats == NULL) + { + stats = (GistBulkDeleteResult *) palloc0(sizeof(GistBulkDeleteResult)); + /* use heap's tuple count */ + Assert(info->num_heap_tuples >= 0); + stats->std.num_index_tuples = info->num_heap_tuples; + /* + * XXX the above is wrong if index is partial. Would it be OK to + * just return NULL, or is there work we must do below? + */ + } + /* gistVacuumUpdate may cause hard work */ if (info->vacuum_full) { @@ -460,13 +473,6 @@ gistvacuumcleanup(PG_FUNCTION_ARGS) if (info->vacuum_full) UnlockRelation(rel, AccessExclusiveLock); - /* if gistbulkdelete skipped the scan, use heap's tuple count */ - if (stats->std.num_index_tuples < 0) - { - Assert(info->num_heap_tuples >= 0); - stats->std.num_index_tuples = info->num_heap_tuples; - } - PG_RETURN_POINTER(stats); } @@ -509,36 +515,22 @@ pushStackIfSplited(Page page, GistBDItem *stack) Datum gistbulkdelete(PG_FUNCTION_ARGS) { - Relation rel = (Relation) PG_GETARG_POINTER(0); - IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(1); - void *callback_state = (void *) PG_GETARG_POINTER(2); - GistBulkDeleteResult *result; + IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0); + GistBulkDeleteResult *stats = (GistBulkDeleteResult *) PG_GETARG_POINTER(1); + IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(2); + void *callback_state = (void *) PG_GETARG_POINTER(3); + Relation rel = info->index; GistBDItem *stack, *ptr; - bool needLock; - result = (GistBulkDeleteResult *) palloc0(sizeof(GistBulkDeleteResult)); + /* first time through? */ + if (stats == NULL) + stats = (GistBulkDeleteResult *) palloc0(sizeof(GistBulkDeleteResult)); + /* we'll re-count the tuples each time */ + stats->std.num_index_tuples = 0; - /* - * We can skip the scan entirely if there's nothing to delete (indicated - * by callback_state == NULL) and the index isn't partial. For a partial - * index we must scan in order to derive a trustworthy tuple count. - * - * XXX as of PG 8.2 this is dead code because GIST indexes are always - * effectively partial ... but keep it anyway in case our null-handling - * gets fixed. - */ - if (callback_state || vac_is_partial_index(rel)) - { - stack = (GistBDItem *) palloc0(sizeof(GistBDItem)); - stack->blkno = GIST_ROOT_BLKNO; - } - else - { - /* skip scan and set flag for gistvacuumcleanup */ - stack = NULL; - result->std.num_index_tuples = -1; - } + stack = (GistBDItem *) palloc0(sizeof(GistBDItem)); + stack->blkno = GIST_ROOT_BLKNO; while (stack) { @@ -601,11 +593,11 @@ gistbulkdelete(PG_FUNCTION_ARGS) i--; maxoff--; ntodelete++; - result->std.tuples_removed += 1; + stats->std.tuples_removed += 1; Assert(maxoff == PageGetMaxOffsetNumber(page)); } else - result->std.num_index_tuples += 1; + stats->std.num_index_tuples += 1; } if (ntodelete) @@ -658,7 +650,7 @@ gistbulkdelete(PG_FUNCTION_ARGS) stack->next = ptr; if (GistTupleIsInvalid(idxtuple)) - result->needFullVacuum = true; + stats->needFullVacuum = true; } } @@ -671,13 +663,5 @@ gistbulkdelete(PG_FUNCTION_ARGS) vacuum_delay_point(); } - needLock = !RELATION_IS_LOCAL(rel); - - if (needLock) - LockRelationForExtension(rel, ExclusiveLock); - result->std.num_pages = RelationGetNumberOfBlocks(rel); - if (needLock) - UnlockRelationForExtension(rel, ExclusiveLock); - - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(stats); } diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 8e232414dc8..ff54052f6de 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.88 2006/03/24 04:32:12 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.89 2006/05/02 22:25:10 tgl Exp $ * * NOTES * This file contains only the public interface routines. @@ -478,11 +478,11 @@ hashrestrpos(PG_FUNCTION_ARGS) Datum hashbulkdelete(PG_FUNCTION_ARGS) { - Relation rel = (Relation) PG_GETARG_POINTER(0); - IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(1); - void *callback_state = (void *) PG_GETARG_POINTER(2); - IndexBulkDeleteResult *result; - BlockNumber num_pages; + IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(1); + IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(2); + void *callback_state = (void *) PG_GETARG_POINTER(3); + Relation rel = info->index; double tuples_removed; double num_index_tuples; double orig_ntuples; @@ -517,18 +517,6 @@ hashbulkdelete(PG_FUNCTION_ARGS) cur_maxbucket = orig_maxbucket; loop_top: - - /* - * If we don't have anything to delete, skip the scan, and report the - * number of tuples shown in the metapage. (Unlike btree and gist, - * we can trust this number even for a partial index.) - */ - if (!callback_state) - { - cur_bucket = cur_maxbucket + 1; - num_index_tuples = local_metapage.hashm_ntuples; - } - while (cur_bucket <= cur_maxbucket) { BlockNumber bucket_blkno; @@ -657,14 +645,37 @@ loop_top: _hash_wrtbuf(rel, metabuf); /* return statistics */ - num_pages = RelationGetNumberOfBlocks(rel); + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + stats->num_index_tuples = num_index_tuples; + stats->tuples_removed += tuples_removed; + /* hashvacuumcleanup will fill in num_pages */ + + PG_RETURN_POINTER(stats); +} - result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); - result->num_pages = num_pages; - result->num_index_tuples = num_index_tuples; - result->tuples_removed = tuples_removed; +/* + * Post-VACUUM cleanup. + * + * Result: a palloc'd struct containing statistical info for VACUUM displays. + */ +Datum +hashvacuumcleanup(PG_FUNCTION_ARGS) +{ + IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(1); + Relation rel = info->index; + BlockNumber num_pages; + + /* If hashbulkdelete wasn't called, return NULL signifying no change */ + if (stats == NULL) + PG_RETURN_POINTER(NULL); + + /* update statistics */ + num_pages = RelationGetNumberOfBlocks(rel); + stats->num_pages = num_pages; - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(stats); } diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 8b19d5def26..b54364acb6d 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.91 2006/03/05 15:58:21 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.92 2006/05/02 22:25:10 tgl Exp $ * * INTERFACE ROUTINES * index_open - open an index relation by relation OID @@ -684,19 +684,17 @@ index_getmulti(IndexScanDesc scan, * * callback routine tells whether a given main-heap tuple is * to be deleted - * - * if callback_state is NULL then there are no tuples to be deleted; - * index AM can choose to avoid work in this case, but must still - * follow the protocol of returning statistical info. * * return value is an optional palloc'd struct of statistics * ---------------- */ IndexBulkDeleteResult * -index_bulk_delete(Relation indexRelation, +index_bulk_delete(IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state) { + Relation indexRelation = info->index; FmgrInfo *procedure; IndexBulkDeleteResult *result; @@ -704,8 +702,9 @@ index_bulk_delete(Relation indexRelation, GET_REL_PROCEDURE(ambulkdelete); result = (IndexBulkDeleteResult *) - DatumGetPointer(FunctionCall3(procedure, - PointerGetDatum(indexRelation), + DatumGetPointer(FunctionCall4(procedure, + PointerGetDatum(info), + PointerGetDatum(stats), PointerGetDatum((Pointer) callback), PointerGetDatum(callback_state))); @@ -719,26 +718,20 @@ index_bulk_delete(Relation indexRelation, * ---------------- */ IndexBulkDeleteResult * -index_vacuum_cleanup(Relation indexRelation, - IndexVacuumCleanupInfo *info, +index_vacuum_cleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { + Relation indexRelation = info->index; FmgrInfo *procedure; IndexBulkDeleteResult *result; RELATION_CHECKS; - - /* It's okay for an index AM not to have a vacuumcleanup procedure */ - if (!RegProcedureIsValid(indexRelation->rd_am->amvacuumcleanup)) - return stats; - GET_REL_PROCEDURE(amvacuumcleanup); result = (IndexBulkDeleteResult *) - DatumGetPointer(FunctionCall3(procedure, - PointerGetDatum(indexRelation), - PointerGetDatum((Pointer) info), - PointerGetDatum((Pointer) stats))); + DatumGetPointer(FunctionCall2(procedure, + PointerGetDatum(info), + PointerGetDatum(stats))); return result; } diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 4f6915e32b4..1eece10398e 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 - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.145 2006/04/25 22:46:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.146 2006/05/02 22:25:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -518,15 +518,15 @@ btrestrpos(PG_FUNCTION_ARGS) Datum btbulkdelete(PG_FUNCTION_ARGS) { - Relation rel = (Relation) PG_GETARG_POINTER(0); - IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(1); - void *callback_state = (void *) PG_GETARG_POINTER(2); - IndexBulkDeleteResult *result; + IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(1); + IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(2); + void *callback_state = (void *) PG_GETARG_POINTER(3); + Relation rel = info->index; double tuples_removed = 0; OffsetNumber deletable[MaxOffsetNumber]; int ndeletable; Buffer buf; - BlockNumber num_pages; /* * The outer loop iterates over index leaf pages, the inner over items on @@ -543,14 +543,8 @@ btbulkdelete(PG_FUNCTION_ARGS) * further to its right, which the indexscan will have no pin on.) We can * skip obtaining exclusive lock on empty pages though, since no indexscan * could be stopped on those. - * - * We can skip the scan entirely if there's nothing to delete (indicated - * by callback_state == NULL). */ - if (callback_state) - buf = _bt_get_endpoint(rel, 0, false); - else - buf = InvalidBuffer; + buf = _bt_get_endpoint(rel, 0, false); if (BufferIsValid(buf)) /* check for empty index */ { @@ -626,14 +620,12 @@ btbulkdelete(PG_FUNCTION_ARGS) } /* return statistics */ - num_pages = RelationGetNumberOfBlocks(rel); - - result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); - result->num_pages = num_pages; - /* btvacuumcleanup will fill in num_index_tuples */ - result->tuples_removed = tuples_removed; + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + stats->tuples_removed += tuples_removed; + /* btvacuumcleanup will fill in num_pages and num_index_tuples */ - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(stats); } /* @@ -646,9 +638,9 @@ btbulkdelete(PG_FUNCTION_ARGS) Datum btvacuumcleanup(PG_FUNCTION_ARGS) { - Relation rel = (Relation) PG_GETARG_POINTER(0); - IndexVacuumCleanupInfo *info = (IndexVacuumCleanupInfo *) PG_GETARG_POINTER(1); - IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(2); + IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(1); + Relation rel = info->index; BlockNumber num_pages; BlockNumber blkno; BlockNumber *freePages; @@ -660,7 +652,9 @@ btvacuumcleanup(PG_FUNCTION_ARGS) MemoryContext oldcontext; bool needLock; - Assert(stats != NULL); + /* Set up all-zero stats if btbulkdelete wasn't called */ + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); /* * First find out the number of pages in the index. We must acquire the |