From 1283b804697902b70e9cd234e36b853b126d6efe Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 15 Oct 2019 17:03:22 +0900 Subject: [PATCH v33 1/3] Add index AM field and callback for parallel index vacuum --- contrib/bloom/blutils.c | 5 ++++ doc/src/sgml/indexam.sgml | 21 ++++++++++++++ src/backend/access/brin/brin.c | 5 ++++ src/backend/access/gin/ginutil.c | 5 ++++ src/backend/access/gist/gist.c | 5 ++++ src/backend/access/hash/hash.c | 4 +++ src/backend/access/index/indexam.c | 29 +++++++++++++++++++ src/backend/access/nbtree/nbtree.c | 4 +++ src/backend/access/spgist/spgutils.c | 5 ++++ src/include/access/amapi.h | 13 +++++++++ src/include/access/genam.h | 1 + src/include/commands/vacuum.h | 28 ++++++++++++++++++ .../modules/dummy_index_am/dummy_index_am.c | 4 +++ 13 files changed, 129 insertions(+) diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index e2063bac62..cde36c5b49 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -18,6 +18,7 @@ #include "access/reloptions.h" #include "bloom.h" #include "catalog/index.h" +#include "commands/vacuum.h" #include "miscadmin.h" #include "storage/bufmgr.h" #include "storage/freespace.h" @@ -121,6 +122,9 @@ blhandler(PG_FUNCTION_ARGS) amroutine->ampredlocks = false; amroutine->amcanparallel = false; amroutine->amcaninclude = false; + amroutine->amparallelvacuumoptions = + VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_CLEANUP; + amroutine->amusemaintenanceworkmem = false; amroutine->amkeytype = InvalidOid; amroutine->ambuild = blbuild; @@ -144,6 +148,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 dd54c68802..693171dc4f 100644 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@ -122,6 +122,10 @@ typedef struct IndexAmRoutine bool amcanparallel; /* does AM support columns included with clause INCLUDE? */ bool amcaninclude; + /* OR of parallel vacuum flags */ + uint8 amparallelvacuumoptions; + /* does AM use maintenance_work_mem? */ + bool amusemaintenanceworkmem; /* type of data stored in index, or InvalidOid if variable */ Oid amkeytype; @@ -149,6 +153,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; @@ -731,6 +738,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 294ffa6e20..fbb4af9df1 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -27,6 +27,7 @@ #include "access/xloginsert.h" #include "catalog/index.h" #include "catalog/pg_am.h" +#include "commands/vacuum.h" #include "miscadmin.h" #include "pgstat.h" #include "postmaster/autovacuum.h" @@ -101,6 +102,9 @@ brinhandler(PG_FUNCTION_ARGS) amroutine->ampredlocks = false; amroutine->amcanparallel = false; amroutine->amcaninclude = false; + amroutine->amparallelvacuumoptions = + VACUUM_OPTION_PARALLEL_CLEANUP; + amroutine->amusemaintenanceworkmem = false; amroutine->amkeytype = InvalidOid; amroutine->ambuild = brinbuild; @@ -124,6 +128,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 38593554f0..8c174b28fc 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -20,6 +20,7 @@ #include "access/xloginsert.h" #include "catalog/pg_collation.h" #include "catalog/pg_type.h" +#include "commands/vacuum.h" #include "miscadmin.h" #include "storage/indexfsm.h" #include "storage/lmgr.h" @@ -53,6 +54,9 @@ ginhandler(PG_FUNCTION_ARGS) amroutine->ampredlocks = true; amroutine->amcanparallel = false; amroutine->amcaninclude = false; + amroutine->amparallelvacuumoptions = + VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_CLEANUP; + amroutine->amusemaintenanceworkmem = true; amroutine->amkeytype = InvalidOid; amroutine->ambuild = ginbuild; @@ -76,6 +80,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 8d9c8d025d..bbb630fb88 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -17,6 +17,7 @@ #include "access/gist_private.h" #include "access/gistscan.h" #include "catalog/pg_collation.h" +#include "commands/vacuum.h" #include "miscadmin.h" #include "nodes/execnodes.h" #include "storage/lmgr.h" @@ -74,6 +75,9 @@ gisthandler(PG_FUNCTION_ARGS) amroutine->ampredlocks = true; amroutine->amcanparallel = false; amroutine->amcaninclude = true; + amroutine->amparallelvacuumoptions = + VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_COND_CLEANUP; + amroutine->amusemaintenanceworkmem = false; amroutine->amkeytype = InvalidOid; amroutine->ambuild = gistbuild; @@ -97,6 +101,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 a0597a0c6e..10d6efdd9f 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -72,6 +72,9 @@ hashhandler(PG_FUNCTION_ARGS) amroutine->ampredlocks = true; amroutine->amcanparallel = false; amroutine->amcaninclude = false; + amroutine->amparallelvacuumoptions = + VACUUM_OPTION_PARALLEL_BULKDEL; + amroutine->amusemaintenanceworkmem = false; amroutine->amkeytype = INT4OID; amroutine->ambuild = hashbuild; @@ -95,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 4cfd5289ad..6a8d12ecbf 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -123,6 +123,9 @@ bthandler(PG_FUNCTION_ARGS) amroutine->ampredlocks = true; amroutine->amcanparallel = true; amroutine->amcaninclude = true; + amroutine->amparallelvacuumoptions = + VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_COND_CLEANUP; + amroutine->amusemaintenanceworkmem = false; amroutine->amkeytype = InvalidOid; amroutine->ambuild = btbuild; @@ -146,6 +149,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 45472db147..bb3e855cce 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -22,6 +22,7 @@ #include "access/transam.h" #include "access/xact.h" #include "catalog/pg_amop.h" +#include "commands/vacuum.h" #include "storage/bufmgr.h" #include "storage/indexfsm.h" #include "storage/lmgr.h" @@ -56,6 +57,9 @@ spghandler(PG_FUNCTION_ARGS) amroutine->ampredlocks = false; amroutine->amcanparallel = false; amroutine->amcaninclude = false; + amroutine->amparallelvacuumoptions = + VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_COND_CLEANUP; + amroutine->amusemaintenanceworkmem = false; amroutine->amkeytype = InvalidOid; amroutine->ambuild = spgbuild; @@ -79,6 +83,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 6e3db06eed..0fd399442d 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. @@ -197,6 +203,10 @@ typedef struct IndexAmRoutine bool amcanparallel; /* does AM support columns included with clause INCLUDE? */ bool amcaninclude; + /* OR of parallel vacuum flags */ + uint8 amparallelvacuumoptions; + /* does AM use maintenance_work_mem? */ + bool amusemaintenanceworkmem; /* type of data stored in index, or InvalidOid if variable */ Oid amkeytype; @@ -230,6 +240,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/include/commands/vacuum.h b/src/include/commands/vacuum.h index 128f7ae65d..7b6f269785 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -23,6 +23,34 @@ #include "storage/lock.h" #include "utils/relcache.h" +/* + * Flags amparallelvacuumoptions to control participation + * of bulkdelete and vacuumcleanup. Both are disabled by + * default. + */ +#define VACUUM_OPTION_NO_PARALLEL 0 + +/* bulkdelete can be performed in parallel */ +#define VACUUM_OPTION_PARALLEL_BULKDEL (1 << 0) + +/* + * vacuumcleanup can be performed in parallel if bulkdelete is + * not performed yet. + */ +#define VACUUM_OPTION_PARALLEL_COND_CLEANUP (1 << 1) + +/* vacuumcleanup can be performed in parallel */ +#define VACUUM_OPTION_PARALLEL_CLEANUP (1 << 2) + +/* value for checking vacuum flags */ +#define VACUUM_OPTION_MAX_VALID_VALUE ((1 << 3) - 1) + +/* Macros for parallel vacuum options */ +#define VACUUM_OPTION_SUPPORT_PARALLEL_BULKDEL(flag) \ + ((((flag) & VACUUM_OPTION_PARALLEL_BULKDEL)) != 0) +#define VACUUM_OPTION_SUPPORT_PARALLEL_CLEANUP(flag) \ + ((((flag) & VACUUM_OPTION_PARALLEL_COND_CLEANUP) != 0) || \ + (((flag) & VACUUM_OPTION_PARALLEL_CLEANUP) != 0)) /*---------- * ANALYZE builds one of these structs for each attribute (column) that is 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 053636e4b4..096534a6ee 100644 --- a/src/test/modules/dummy_index_am/dummy_index_am.c +++ b/src/test/modules/dummy_index_am/dummy_index_am.c @@ -16,6 +16,7 @@ #include "access/amapi.h" #include "access/reloptions.h" #include "catalog/index.h" +#include "commands/vacuum.h" #include "nodes/pathnodes.h" #include "utils/guc.h" #include "utils/rel.h" @@ -294,6 +295,8 @@ dihandler(PG_FUNCTION_ARGS) amroutine->ampredlocks = false; amroutine->amcanparallel = false; amroutine->amcaninclude = false; + amroutine->amparallelvacuumoptions = VACUUM_OPTION_NO_PARALLEL; + amroutine->amusemaintenanceworkmem = false; amroutine->amkeytype = InvalidOid; amroutine->ambuild = dibuild; @@ -317,6 +320,7 @@ dihandler(PG_FUNCTION_ARGS) amroutine->amestimateparallelscan = NULL; amroutine->aminitparallelscan = NULL; amroutine->amparallelrescan = NULL; + amroutine->amestimateparallelvacuum = NULL; PG_RETURN_POINTER(amroutine); } -- 2.23.0