mirror of
https://github.com/postgres/postgres.git
synced 2025-07-11 10:01:57 +03:00
Restructure index AM interface for index building and index tuple deletion,
per previous discussion on pghackers. Most of the duplicate code in different AMs' ambuild routines has been moved out to a common routine in index.c; this means that all index types now do the right things about inserting recently-dead tuples, etc. (I also removed support for EXTEND INDEX in the ambuild routines, since that's about to go away anyway, and it cluttered the code a lot.) The retail indextuple deletion routines have been replaced by a "bulk delete" routine in which the indexscan is inside the access method. I haven't pushed this change as far as it should go yet, but it should allow considerable simplification of the internal bookkeeping for deletions. Also, add flag columns to pg_am to eliminate various hardcoded tests on AM OIDs, and remove unused pg_am columns. Fix rtree and gist index types to not attempt to store NULLs; before this, gist usually crashed, while rtree managed not to crash but computed wacko bounding boxes for NULL entries (which might have had something to do with the performance problems we've heard about occasionally). Add AtEOXact routines to hash, rtree, and gist, all of which have static state that needs to be reset after an error. We discovered this need long ago for btree, but missed the other guys. Oh, one more thing: concurrent VACUUM is now the default.
This commit is contained in:
@ -31,7 +31,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.1 2001/07/13 22:55:59 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.2 2001/07/15 22:48:17 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -112,7 +112,7 @@ static void lazy_record_dead_tuple(LVRelStats *vacrelstats,
|
||||
ItemPointer itemptr);
|
||||
static void lazy_record_free_space(LVRelStats *vacrelstats,
|
||||
BlockNumber page, Size avail);
|
||||
static bool lazy_tid_reaped(ItemPointer itemptr, LVRelStats *vacrelstats);
|
||||
static bool lazy_tid_reaped(ItemPointer itemptr, void *state);
|
||||
static void lazy_update_fsm(Relation onerel, LVRelStats *vacrelstats);
|
||||
static int vac_cmp_itemptr(const void *left, const void *right);
|
||||
|
||||
@ -371,11 +371,11 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
|
||||
|
||||
if (pgchanged)
|
||||
{
|
||||
WriteBuffer(buf);
|
||||
SetBufferCommitInfoNeedsSave(buf);
|
||||
changed_pages++;
|
||||
}
|
||||
else
|
||||
ReleaseBuffer(buf);
|
||||
|
||||
ReleaseBuffer(buf);
|
||||
}
|
||||
|
||||
/* If any tuples need to be deleted, perform final vacuum cycle */
|
||||
@ -507,64 +507,40 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
|
||||
static void
|
||||
lazy_vacuum_index(Relation indrel, LVRelStats *vacrelstats)
|
||||
{
|
||||
RetrieveIndexResult res;
|
||||
IndexScanDesc iscan;
|
||||
int tups_vacuumed;
|
||||
BlockNumber num_pages;
|
||||
double num_index_tuples;
|
||||
IndexBulkDeleteResult *stats;
|
||||
VacRUsage ru0;
|
||||
|
||||
vac_init_rusage(&ru0);
|
||||
|
||||
/*
|
||||
* Only btree and hash indexes are currently safe for concurrent access;
|
||||
* see notes in ExecOpenIndices(). XXX should rely on index AM for this
|
||||
* If index is unsafe for concurrent access, must lock it.
|
||||
*/
|
||||
if (indrel->rd_rel->relam != BTREE_AM_OID &&
|
||||
indrel->rd_rel->relam != HASH_AM_OID)
|
||||
if (! indrel->rd_am->amconcurrent)
|
||||
LockRelation(indrel, AccessExclusiveLock);
|
||||
|
||||
/* XXX should use a bulk-delete call here */
|
||||
|
||||
/* walk through the entire index */
|
||||
iscan = index_beginscan(indrel, false, 0, (ScanKey) NULL);
|
||||
tups_vacuumed = 0;
|
||||
num_index_tuples = 0;
|
||||
|
||||
while ((res = index_getnext(iscan, ForwardScanDirection))
|
||||
!= (RetrieveIndexResult) NULL)
|
||||
{
|
||||
ItemPointer heapptr = &res->heap_iptr;
|
||||
|
||||
if (lazy_tid_reaped(heapptr, vacrelstats))
|
||||
{
|
||||
index_delete(indrel, &res->index_iptr);
|
||||
++tups_vacuumed;
|
||||
}
|
||||
else
|
||||
num_index_tuples += 1;
|
||||
|
||||
pfree(res);
|
||||
}
|
||||
|
||||
index_endscan(iscan);
|
||||
|
||||
/* now update statistics in pg_class */
|
||||
num_pages = RelationGetNumberOfBlocks(indrel);
|
||||
vac_update_relstats(RelationGetRelid(indrel),
|
||||
num_pages, num_index_tuples, false);
|
||||
/* Do bulk deletion */
|
||||
stats = index_bulk_delete(indrel, lazy_tid_reaped, (void *) vacrelstats);
|
||||
|
||||
/*
|
||||
* Release lock acquired above.
|
||||
*/
|
||||
if (indrel->rd_rel->relam != BTREE_AM_OID &&
|
||||
indrel->rd_rel->relam != HASH_AM_OID)
|
||||
if (! indrel->rd_am->amconcurrent)
|
||||
UnlockRelation(indrel, AccessExclusiveLock);
|
||||
|
||||
elog(MESSAGE_LEVEL, "Index %s: Pages %u; Tuples %.0f: Deleted %u.\n\t%s",
|
||||
RelationGetRelationName(indrel), num_pages,
|
||||
num_index_tuples, tups_vacuumed,
|
||||
vac_show_rusage(&ru0));
|
||||
/* now update statistics in pg_class */
|
||||
if (stats)
|
||||
{
|
||||
vac_update_relstats(RelationGetRelid(indrel),
|
||||
stats->num_pages, stats->num_index_tuples,
|
||||
false);
|
||||
|
||||
elog(MESSAGE_LEVEL, "Index %s: Pages %u; Tuples %.0f: Deleted %.0f.\n\t%s",
|
||||
RelationGetRelationName(indrel), stats->num_pages,
|
||||
stats->num_index_tuples, stats->tuples_removed,
|
||||
vac_show_rusage(&ru0));
|
||||
|
||||
pfree(stats);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -960,11 +936,14 @@ lazy_record_free_space(LVRelStats *vacrelstats,
|
||||
/*
|
||||
* lazy_tid_reaped() -- is a particular tid deletable?
|
||||
*
|
||||
* This has the right signature to be an IndexBulkDeleteCallback.
|
||||
*
|
||||
* Assumes dead_tuples array is in sorted order.
|
||||
*/
|
||||
static bool
|
||||
lazy_tid_reaped(ItemPointer itemptr, LVRelStats *vacrelstats)
|
||||
lazy_tid_reaped(ItemPointer itemptr, void *state)
|
||||
{
|
||||
LVRelStats *vacrelstats = (LVRelStats *) state;
|
||||
ItemPointer res;
|
||||
|
||||
res = (ItemPointer) bsearch((void *) itemptr,
|
||||
|
Reference in New Issue
Block a user