Switched to TidStore for HNSW vacuuming for Postgres 17+ [skip ci]

This commit is contained in:
Andrew Kane
2026-07-01 16:28:49 -07:00
parent 89fda3e100
commit 0587d4b834
3 changed files with 47 additions and 3 deletions

View File

@@ -290,7 +290,11 @@ hnswhandler(PG_FUNCTION_ARGS)
.amcanparallel = false, .amcanparallel = false,
.amcanbuildparallel = true, .amcanbuildparallel = true,
.amcaninclude = false, .amcaninclude = false,
#if PG_VERSION_NUM >= 170000
.amusemaintenanceworkmem = true,
#else
.amusemaintenanceworkmem = false, .amusemaintenanceworkmem = false,
#endif
.amsummarizing = false, .amsummarizing = false,
.amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL, .amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL,
.amkeytype = InvalidOid, .amkeytype = InvalidOid,
@@ -351,7 +355,11 @@ hnswhandler(PG_FUNCTION_ARGS)
amroutine->amcanbuildparallel = true; amroutine->amcanbuildparallel = true;
#endif #endif
amroutine->amcaninclude = false; amroutine->amcaninclude = false;
amroutine->amusemaintenanceworkmem = false; /* not used during VACUUM */ #if PG_VERSION_NUM >= 170000
amroutine->amusemaintenanceworkmem = true;
#else
amroutine->amusemaintenanceworkmem = false;
#endif
#if PG_VERSION_NUM >= 160000 #if PG_VERSION_NUM >= 160000
amroutine->amsummarizing = false; amroutine->amsummarizing = false;
#endif #endif

View File

@@ -26,6 +26,12 @@
typedef Pointer Item; typedef Pointer Item;
#endif #endif
#if PG_VERSION_NUM >= 170000
#define HnswTidStore TidStore
#else
#define HnswTidStore tidhash_hash
#endif
#define HNSW_MAX_DIM 2000 #define HNSW_MAX_DIM 2000
#define HNSW_MAX_NNZ 1000 #define HNSW_MAX_NNZ 1000
@@ -427,7 +433,7 @@ typedef struct HnswVacuumState
HnswSupport support; HnswSupport support;
/* Variables */ /* Variables */
struct tidhash_hash *deleting; struct HnswTidStore *deleting;
BufferAccessStrategy bas; BufferAccessStrategy bas;
HnswNeighborTuple ntup; HnswNeighborTuple ntup;
HnswElementData highestPoint; HnswElementData highestPoint;

View File

@@ -10,6 +10,12 @@
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/rel.h" #include "utils/rel.h"
#if PG_VERSION_NUM >= 170000
#include "access/tidstore.h"
#include "miscadmin.h"
#include "postmaster/autovacuum.h"
#endif
#if PG_VERSION_NUM >= 160000 #if PG_VERSION_NUM >= 160000
#include "varatt.h" #include "varatt.h"
#endif #endif
@@ -22,9 +28,13 @@
* Check if deletion list contains an element * Check if deletion list contains an element
*/ */
static bool static bool
DeletingElement(tidhash_hash * deleting, ItemPointer indextid) DeletingElement(HnswTidStore * deleting, ItemPointer indextid)
{ {
#if PG_VERSION_NUM >= 170000
return TidStoreIsMember(deleting, indextid);
#else
return tidhash_lookup(deleting, *indextid) != NULL; return tidhash_lookup(deleting, *indextid) != NULL;
#endif
} }
/* /*
@@ -60,6 +70,10 @@ RemoveHeapTids(HnswVacuumState * vacuumstate)
OffsetNumber offno; OffsetNumber offno;
OffsetNumber maxoffno; OffsetNumber maxoffno;
bool updated = false; bool updated = false;
#if PG_VERSION_NUM >= 170000
OffsetNumber deletedoffs[MaxOffsetNumber];
int ndeletedoffs = 0;
#endif
vacuum_delay_point(); vacuum_delay_point();
@@ -121,6 +135,9 @@ RemoveHeapTids(HnswVacuumState * vacuumstate)
if (!ItemPointerIsValid(&etup->heaptids[0])) if (!ItemPointerIsValid(&etup->heaptids[0]))
{ {
#if PG_VERSION_NUM >= 170000
deletedoffs[ndeletedoffs++] = offno;
#else
ItemPointerData indextid; ItemPointerData indextid;
bool found; bool found;
@@ -129,6 +146,7 @@ RemoveHeapTids(HnswVacuumState * vacuumstate)
tidhash_insert(vacuumstate->deleting, indextid, &found); tidhash_insert(vacuumstate->deleting, indextid, &found);
Assert(!found); Assert(!found);
#endif
} }
else if (etup->level > highestLevel) else if (etup->level > highestLevel)
{ {
@@ -157,6 +175,10 @@ RemoveHeapTids(HnswVacuumState * vacuumstate)
} }
} }
#if PG_VERSION_NUM >= 170000
TidStoreSetBlockOffsets(vacuumstate->deleting, blkno, deletedoffs, ndeletedoffs);
#endif
blkno = HnswPageGetOpaque(page)->nextblkno; blkno = HnswPageGetOpaque(page)->nextblkno;
if (updated) if (updated)
@@ -756,7 +778,11 @@ InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkD
HnswGetMetaPageInfo(index, &vacuumstate->m, NULL); HnswGetMetaPageInfo(index, &vacuumstate->m, NULL);
/* Create hash table */ /* Create hash table */
#if PG_VERSION_NUM >= 170000
vacuumstate->deleting = TidStoreCreateLocal((AmAutoVacuumWorkerProcess() && autovacuum_work_mem != -1) ? autovacuum_work_mem : maintenance_work_mem, true);
#else
vacuumstate->deleting = tidhash_create(CurrentMemoryContext, 256, NULL); vacuumstate->deleting = tidhash_create(CurrentMemoryContext, 256, NULL);
#endif
} }
/* /*
@@ -765,7 +791,11 @@ InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkD
static void static void
FreeVacuumState(HnswVacuumState * vacuumstate) FreeVacuumState(HnswVacuumState * vacuumstate)
{ {
#if PG_VERSION_NUM >= 170000
TidStoreDestroy(vacuumstate->deleting);
#else
tidhash_destroy(vacuumstate->deleting); tidhash_destroy(vacuumstate->deleting);
#endif
FreeAccessStrategy(vacuumstate->bas); FreeAccessStrategy(vacuumstate->bas);
pfree(vacuumstate->ntup); pfree(vacuumstate->ntup);
MemoryContextDelete(vacuumstate->tmpCtx); MemoryContextDelete(vacuumstate->tmpCtx);