From 57c5c5199255227bc75ed7ba1b2a5f70136f17f8 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Mon, 4 Jan 2021 13:34:10 +0900 Subject: [PATCH v2 1/3] Introduce IndexAM API for choosing index vacuum strategy. --- contrib/bloom/bloom.h | 2 ++ contrib/bloom/blutils.c | 1 + contrib/bloom/blvacuum.c | 13 +++++++++++++ src/backend/access/brin/brin.c | 1 + src/backend/access/gin/ginutil.c | 1 + src/backend/access/gin/ginvacuum.c | 13 +++++++++++++ src/backend/access/gist/gist.c | 1 + src/backend/access/gist/gistvacuum.c | 13 +++++++++++++ src/backend/access/hash/hash.c | 14 ++++++++++++++ src/backend/access/index/indexam.c | 22 ++++++++++++++++++++++ src/backend/access/nbtree/nbtree.c | 14 ++++++++++++++ src/backend/access/spgist/spgutils.c | 1 + src/backend/access/spgist/spgvacuum.c | 13 +++++++++++++ src/include/access/amapi.h | 7 ++++++- src/include/access/genam.h | 16 ++++++++++++++-- src/include/access/gin_private.h | 2 ++ src/include/access/gist_private.h | 2 ++ src/include/access/hash.h | 2 ++ src/include/access/nbtree.h | 2 ++ src/include/access/spgist.h | 2 ++ 20 files changed, 139 insertions(+), 3 deletions(-) diff --git a/contrib/bloom/bloom.h b/contrib/bloom/bloom.h index a22a6dfa40..8395d31450 100644 --- a/contrib/bloom/bloom.h +++ b/contrib/bloom/bloom.h @@ -202,6 +202,8 @@ extern void blendscan(IndexScanDesc scan); extern IndexBuildResult *blbuild(Relation heap, Relation index, struct IndexInfo *indexInfo); extern void blbuildempty(Relation index); +extern IndexVacuumStrategy blvacuumstrategy(IndexVacuumInfo *info, + struct VacuumParams *params); extern IndexBulkDeleteResult *blbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state); diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index 1e505b1da5..8098d75c82 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -131,6 +131,7 @@ blhandler(PG_FUNCTION_ARGS) amroutine->ambuild = blbuild; amroutine->ambuildempty = blbuildempty; amroutine->aminsert = blinsert; + amroutine->amvacuumstrategy = blvacuumstrategy; amroutine->ambulkdelete = blbulkdelete; amroutine->amvacuumcleanup = blvacuumcleanup; amroutine->amcanreturn = NULL; diff --git a/contrib/bloom/blvacuum.c b/contrib/bloom/blvacuum.c index 88b0a6d290..b5b8df34ed 100644 --- a/contrib/bloom/blvacuum.c +++ b/contrib/bloom/blvacuum.c @@ -23,6 +23,19 @@ #include "storage/lmgr.h" +/* + * Choose the vacuum strategy. Do bulk-deletion unless index cleanup + * is specified to off. + */ +IndexVacuumStrategy +blvacuumstrategy(IndexVacuumInfo *info, VacuumParams *params) +{ + if (params->index_cleanup == VACOPT_TERNARY_DISABLED) + return INDEX_VACUUM_STRATEGY_NONE; + else + return INDEX_VACUUM_STRATEGY_BULKDELETE; +} + /* * Bulk deletion of all index entries pointing to a set of heap tuples. * The set of target tuples is specified via a callback routine that tells diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 27ba596c6e..181dc51268 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -112,6 +112,7 @@ brinhandler(PG_FUNCTION_ARGS) amroutine->ambuild = brinbuild; amroutine->ambuildempty = brinbuildempty; amroutine->aminsert = brininsert; + amroutine->amvacuumstrategy = NULL; amroutine->ambulkdelete = brinbulkdelete; amroutine->amvacuumcleanup = brinvacuumcleanup; amroutine->amcanreturn = NULL; diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index 6b9b04cf42..fc375332fc 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -63,6 +63,7 @@ ginhandler(PG_FUNCTION_ARGS) amroutine->ambuild = ginbuild; amroutine->ambuildempty = ginbuildempty; amroutine->aminsert = gininsert; + amroutine->amvacuumstrategy = ginvacuumstrategy; amroutine->ambulkdelete = ginbulkdelete; amroutine->amvacuumcleanup = ginvacuumcleanup; amroutine->amcanreturn = NULL; diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index 35b85a9bff..985fb27ba1 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -560,6 +560,19 @@ ginVacuumEntryPage(GinVacuumState *gvs, Buffer buffer, BlockNumber *roots, uint3 return (tmppage == origpage) ? NULL : tmppage; } +/* + * Choose the vacuum strategy. Do bulk-deletion unless index cleanup + * is specified to off. + */ +IndexVacuumStrategy +ginvacuumstrategy(IndexVacuumInfo *info, VacuumParams *params) +{ + if (params->index_cleanup == VACOPT_TERNARY_DISABLED) + return INDEX_VACUUM_STRATEGY_NONE; + else + return INDEX_VACUUM_STRATEGY_BULKDELETE; +} + IndexBulkDeleteResult * ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state) diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 992936cfa8..6d047b9f87 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -84,6 +84,7 @@ gisthandler(PG_FUNCTION_ARGS) amroutine->ambuild = gistbuild; amroutine->ambuildempty = gistbuildempty; amroutine->aminsert = gistinsert; + amroutine->amvacuumstrategy = gistvacuumstrategy; amroutine->ambulkdelete = gistbulkdelete; amroutine->amvacuumcleanup = gistvacuumcleanup; amroutine->amcanreturn = gistcanreturn; diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index 94a7e12763..d462984b3d 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -52,6 +52,19 @@ static bool gistdeletepage(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, Buffer buffer, OffsetNumber downlink, Buffer leafBuffer); +/* + * Choose the vacuum strategy. Do bulk-deletion unless index cleanup + * is specified to off. + */ +IndexVacuumStrategy +gistvacuumstrategy(IndexVacuumInfo *info, VacuumParams *params) +{ + if (params->index_cleanup == VACOPT_TERNARY_DISABLED) + return INDEX_VACUUM_STRATEGY_NONE; + else + return INDEX_VACUUM_STRATEGY_BULKDELETE; +} + /* * VACUUM bulkdelete stage: remove index entries. */ diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 0752fb38a9..fb439d23a8 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -81,6 +81,7 @@ hashhandler(PG_FUNCTION_ARGS) amroutine->ambuild = hashbuild; amroutine->ambuildempty = hashbuildempty; amroutine->aminsert = hashinsert; + amroutine->amvacuumstrategy = hashvacuumstrategy; amroutine->ambulkdelete = hashbulkdelete; amroutine->amvacuumcleanup = hashvacuumcleanup; amroutine->amcanreturn = NULL; @@ -444,6 +445,19 @@ hashendscan(IndexScanDesc scan) scan->opaque = NULL; } +/* + * Choose the vacuum strategy. Do bulk-deletion unless index cleanup + * is specified to off. + */ +IndexVacuumStrategy +hashvacuumstrategy(IndexVacuumInfo *info, VacuumParams *params) +{ + if (params->index_cleanup == VACOPT_TERNARY_DISABLED) + return INDEX_VACUUM_STRATEGY_NONE; + else + return INDEX_VACUUM_STRATEGY_BULKDELETE; +} + /* * Bulk deletion of all index entries pointing to a set of heap tuples. * The set of target tuples is specified via a callback routine that tells diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 3d2dbed708..171ba5c2fa 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -678,6 +678,28 @@ index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap) return ntids; } +/* ---------------- + * index_vacuum_strategy - ask index vacuum strategy + * + * This callback routine is called just before vacuuming the heap. + * Returns IndexVacuumStrategy value to tell the lazy vacuum whether to + * do index deletion. + * ---------------- + */ +IndexVacuumStrategy +index_vacuum_strategy(IndexVacuumInfo *info, struct VacuumParams *params) +{ + Relation indexRelation = info->index; + + RELATION_CHECKS; + + /* amvacuumstrategy is optional; assume do bulk-deletion */ + if (indexRelation->rd_indam->amvacuumstrategy == NULL) + return INDEX_VACUUM_STRATEGY_BULKDELETE; + + return indexRelation->rd_indam->amvacuumstrategy(info, params); +} + /* ---------------- * index_bulk_delete - do mass deletion of index entries * diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 289bd3c15d..863430f910 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -133,6 +133,7 @@ bthandler(PG_FUNCTION_ARGS) amroutine->ambuild = btbuild; amroutine->ambuildempty = btbuildempty; amroutine->aminsert = btinsert; + amroutine->amvacuumstrategy = btvacuumstrategy; amroutine->ambulkdelete = btbulkdelete; amroutine->amvacuumcleanup = btvacuumcleanup; amroutine->amcanreturn = btcanreturn; @@ -864,6 +865,19 @@ _bt_vacuum_needs_cleanup(IndexVacuumInfo *info) return result; } +/* + * Choose the vacuum strategy. Do bulk-deletion unless index cleanup + * is specified to off. + */ +IndexVacuumStrategy +btvacuumstrategy(IndexVacuumInfo *info, VacuumParams *params) +{ + if (params->index_cleanup == VACOPT_TERNARY_DISABLED) + return INDEX_VACUUM_STRATEGY_NONE; + else + return INDEX_VACUUM_STRATEGY_BULKDELETE; +} + /* * Bulk deletion of all index entries pointing to a set of heap tuples. * The set of target tuples is specified via a callback routine that tells diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index d8b1815061..7b2313590a 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -66,6 +66,7 @@ spghandler(PG_FUNCTION_ARGS) amroutine->ambuild = spgbuild; amroutine->ambuildempty = spgbuildempty; amroutine->aminsert = spginsert; + amroutine->amvacuumstrategy = spgvacuumstrategy; amroutine->ambulkdelete = spgbulkdelete; amroutine->amvacuumcleanup = spgvacuumcleanup; amroutine->amcanreturn = spgcanreturn; diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c index 0d02a02222..5de6dd0fdf 100644 --- a/src/backend/access/spgist/spgvacuum.c +++ b/src/backend/access/spgist/spgvacuum.c @@ -894,6 +894,19 @@ spgvacuumscan(spgBulkDeleteState *bds) bds->stats->pages_free = bds->stats->pages_deleted; } +/* + * Choose the vacuum strategy. Do bulk-deletion unless index cleanup + * is specified to off. + */ +IndexVacuumStrategy +spgvacuumstrategy(IndexVacuumInfo *info, VacuumParams *params) +{ + if (params->index_cleanup == VACOPT_TERNARY_DISABLED) + return INDEX_VACUUM_STRATEGY_NONE; + else + return INDEX_VACUUM_STRATEGY_BULKDELETE; +} + /* * Bulk deletion of all index entries pointing to a set of heap tuples. * The set of target tuples is specified via a callback routine that tells diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index d357ebb559..548f2033a4 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -22,8 +22,9 @@ struct PlannerInfo; struct IndexPath; -/* Likewise, this file shouldn't depend on execnodes.h. */ +/* Likewise, this file shouldn't depend on execnodes.h and vacuum.h. */ struct IndexInfo; +struct VacuumParams; /* @@ -112,6 +113,9 @@ typedef bool (*aminsert_function) (Relation indexRelation, IndexUniqueCheck checkUnique, bool indexUnchanged, struct IndexInfo *indexInfo); +/* vacuum strategy */ +typedef IndexVacuumStrategy (*amvacuumstrategy_function) (IndexVacuumInfo *info, + struct VacuumParams *params); /* bulk delete */ typedef IndexBulkDeleteResult *(*ambulkdelete_function) (IndexVacuumInfo *info, @@ -259,6 +263,7 @@ typedef struct IndexAmRoutine ambuild_function ambuild; ambuildempty_function ambuildempty; aminsert_function aminsert; + amvacuumstrategy_function amvacuumstrategy; ambulkdelete_function ambulkdelete; amvacuumcleanup_function amvacuumcleanup; amcanreturn_function amcanreturn; /* can be NULL */ diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 0eab1508d3..6c1c4798e3 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -21,8 +21,9 @@ #include "utils/relcache.h" #include "utils/snapshot.h" -/* We don't want this file to depend on execnodes.h. */ +/* We don't want this file to depend on execnodes.h and vacuum.h. */ struct IndexInfo; +struct VacuumParams; /* * Struct for statistics returned by ambuild @@ -34,7 +35,8 @@ typedef struct IndexBuildResult } IndexBuildResult; /* - * Struct for input arguments passed to ambulkdelete and amvacuumcleanup + * Struct for input arguments passed to amvacuumstrategy, ambulkdelete + * and amvacuumcleanup * * num_heap_tuples is accurate only when estimated_count is false; * otherwise it's just an estimate (currently, the estimate is the @@ -125,6 +127,14 @@ typedef struct IndexOrderByDistance bool isnull; } IndexOrderByDistance; +/* Result value for amvacuumstrategy */ +typedef enum IndexVacuumStrategy +{ + INDEX_VACUUM_STRATEGY_NONE, /* No-op, skip bulk-deletion in this + * vacuum cycle */ + INDEX_VACUUM_STRATEGY_BULKDELETE /* Do ambulkdelete */ +} IndexVacuumStrategy; + /* * generalized index_ interface routines (in indexam.c) */ @@ -174,6 +184,8 @@ extern bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, struct TupleTableSlot *slot); extern int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap); +extern IndexVacuumStrategy index_vacuum_strategy(IndexVacuumInfo *info, + struct VacuumParams *params); extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index 670a40b4be..5c48a48917 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -397,6 +397,8 @@ extern int64 gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm); extern void ginInitConsistentFunction(GinState *ginstate, GinScanKey key); /* ginvacuum.c */ +extern IndexVacuumStrategy ginvacuumstrategy(IndexVacuumInfo *info, + struct VacuumParams *params); extern IndexBulkDeleteResult *ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 553d364e2d..303a18da4d 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -533,6 +533,8 @@ extern void gistMakeUnionKey(GISTSTATE *giststate, int attno, extern XLogRecPtr gistGetFakeLSN(Relation rel); /* gistvacuum.c */ +extern IndexVacuumStrategy gistvacuumstrategy(IndexVacuumInfo *info, + struct VacuumParams *params); extern IndexBulkDeleteResult *gistbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, diff --git a/src/include/access/hash.h b/src/include/access/hash.h index 1cce865be2..4c7e064708 100644 --- a/src/include/access/hash.h +++ b/src/include/access/hash.h @@ -372,6 +372,8 @@ extern IndexScanDesc hashbeginscan(Relation rel, int nkeys, int norderbys); extern void hashrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys); extern void hashendscan(IndexScanDesc scan); +extern IndexVacuumStrategy hashvacuumstrategy(IndexVacuumInfo *info, + struct VacuumParams *params); extern IndexBulkDeleteResult *hashbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index cad4f2bdeb..ba120d4a80 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -1011,6 +1011,8 @@ extern void btparallelrescan(IndexScanDesc scan); extern void btendscan(IndexScanDesc scan); extern void btmarkpos(IndexScanDesc scan); extern void btrestrpos(IndexScanDesc scan); +extern IndexVacuumStrategy btvacuumstrategy(IndexVacuumInfo *info, + struct VacuumParams *params); extern IndexBulkDeleteResult *btbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h index 2eb2f421a8..f591b21ef1 100644 --- a/src/include/access/spgist.h +++ b/src/include/access/spgist.h @@ -212,6 +212,8 @@ extern bool spggettuple(IndexScanDesc scan, ScanDirection dir); extern bool spgcanreturn(Relation index, int attno); /* spgvacuum.c */ +extern IndexVacuumStrategy spgvacuumstrategy(IndexVacuumInfo *info, + struct VacuumParams *params); extern IndexBulkDeleteResult *spgbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, -- 2.27.0