From bf8e8ae5ded91327d504a19227c96378d3d0b513 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Thu, 24 Oct 2019 14:51:16 +0900 Subject: [PATCH v31 2/6] Add an index AM callback to estimate DSM for parallel vacuum --- contrib/bloom/blutils.c | 1 + doc/src/sgml/indexam.sgml | 17 +++++++++++ src/backend/access/brin/brin.c | 1 + src/backend/access/gin/ginutil.c | 1 + src/backend/access/gist/gist.c | 1 + src/backend/access/hash/hash.c | 1 + src/backend/access/index/indexam.c | 29 +++++++++++++++++++ src/backend/access/nbtree/nbtree.c | 1 + src/backend/access/spgist/spgutils.c | 1 + src/include/access/amapi.h | 9 ++++++ src/include/access/genam.h | 1 + .../modules/dummy_index_am/dummy_index_am.c | 1 + 12 files changed, 64 insertions(+) diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index 98163c81bd..9ef14a47f3 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -145,6 +145,7 @@ blhandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = NULL; amroutine->aminitparallelscan = NULL; amroutine->amparallelrescan = NULL; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml index fa5682db04..c3d2352d0f 100644 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@ -151,6 +151,9 @@ typedef struct IndexAmRoutine amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ aminitparallelscan_function aminitparallelscan; /* can be NULL */ amparallelrescan_function amparallelrescan; /* can be NULL */ + + /* interface functions to support parallel vacuum */ + amestimateparallelvacuum_function amestimateparallelvacuum; /* can be NULL */ } IndexAmRoutine; @@ -733,6 +736,20 @@ amparallelrescan (IndexScanDesc scan); the beginning. + + +void +amestimateparallelvacuum (IndexScanDesc scan); + + Estimate and return the number of bytes of dynamic shared memory which the + access method will be needed to copy the statistics to. + + + + It is not necessary to implement this function for access methods which + do not support parallel vacuum or in cases where the access method does not + require more than size of IndexBulkDeleteResult. + diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 6ea48fb555..4045f5eacf 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -125,6 +125,7 @@ brinhandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = NULL; amroutine->aminitparallelscan = NULL; amroutine->amparallelrescan = NULL; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index 0c33809c83..9832f651ef 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -77,6 +77,7 @@ ginhandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = NULL; amroutine->aminitparallelscan = NULL; amroutine->amparallelrescan = NULL; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 0363bf814a..88b1e839b3 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -99,6 +99,7 @@ gisthandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = NULL; amroutine->aminitparallelscan = NULL; amroutine->amparallelrescan = NULL; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index f21d9ac78f..3666318064 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -98,6 +98,7 @@ hashhandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = NULL; amroutine->aminitparallelscan = NULL; amroutine->amparallelrescan = NULL; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 9dfa0ddfbb..5238b9d38f 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -711,6 +711,35 @@ index_vacuum_cleanup(IndexVacuumInfo *info, return indexRelation->rd_indam->amvacuumcleanup(info, stats); } +/* + * index_parallelvacuum_estimate - estimate shared memory for parallel vacuum + * + * Currently, we don't pass any information to the AM-specific estimator, + * so it can probably only return a constant. In the future, we might need + * to pass more information. + */ +Size +index_parallelvacuum_estimate(Relation indexRelation) +{ + Size nbytes; + + RELATION_CHECKS; + + /* + * If amestimateparallelvacuum is not provided, assume only + * IndexBulkDeleteResult is needed. + */ + if (indexRelation->rd_indam->amestimateparallelvacuum != NULL) + { + nbytes = indexRelation->rd_indam->amestimateparallelvacuum(); + Assert(nbytes >= MAXALIGN(sizeof(IndexBulkDeleteResult))); + } + else + nbytes = MAXALIGN(sizeof(IndexBulkDeleteResult)); + + return nbytes; +} + /* ---------------- * index_can_return * diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index e885aadc21..f1db77886c 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -147,6 +147,7 @@ bthandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = btestimateparallelscan; amroutine->aminitparallelscan = btinitparallelscan; amroutine->amparallelrescan = btparallelrescan; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index 0c86b63f65..ff66c3ac6c 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -80,6 +80,7 @@ spghandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = NULL; amroutine->aminitparallelscan = NULL; amroutine->amparallelrescan = NULL; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index f7d2a1b7e3..549912c1c9 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -156,6 +156,12 @@ typedef void (*aminitparallelscan_function) (void *target); /* (re)start parallel index scan */ typedef void (*amparallelrescan_function) (IndexScanDesc scan); +/* + * Callback function signatures - for parallel index vacuuming. + */ +/* estimate size of parallel index vacuuming memory */ +typedef Size (*amestimateparallelvacuum_function) (void); + /* * API struct for an index AM. Note this must be stored in a single palloc'd * chunk of memory. @@ -232,6 +238,9 @@ typedef struct IndexAmRoutine amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ aminitparallelscan_function aminitparallelscan; /* can be NULL */ amparallelrescan_function amparallelrescan; /* can be NULL */ + + /* interface functions to support parallel vacuum */ + amestimateparallelvacuum_function amestimateparallelvacuum; /* can be NULL */ } IndexAmRoutine; diff --git a/src/include/access/genam.h b/src/include/access/genam.h index a813b004be..48ed5bbac7 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -179,6 +179,7 @@ extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info, void *callback_state); extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); +extern Size index_parallelvacuum_estimate(Relation indexRelation); extern bool index_can_return(Relation indexRelation, int attno); extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum); diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c index f12eefbb24..c90405a23b 100644 --- a/src/test/modules/dummy_index_am/dummy_index_am.c +++ b/src/test/modules/dummy_index_am/dummy_index_am.c @@ -325,6 +325,7 @@ dihandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = NULL; amroutine->aminitparallelscan = NULL; amroutine->amparallelrescan = NULL; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } -- 2.22.0