From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jingtang Zhang Date: Sun, 20 Sep 2026 21:23:33 +0800 Subject: [PATCH v1] Use bounded GIN pending-list cleanup in parallel autovacuum Parallel autovacuum workers are regular background workers, so AmAutoVacuumWorkerProcess() returns false for them. As a result, GIN asks these workers to empty the pending list, while the autovacuum leader uses bounded cleanup. Add is_autovacuum to IndexVacuumInfo and pass the leader's shared autovacuum state to parallel workers. Use it in GIN so all participants in an autovacuum use bounded pending-list cleanup. --- src/backend/access/gin/ginvacuum.c | 6 +++--- src/backend/access/heap/vacuumlazy.c | 2 ++ src/backend/catalog/index.c | 1 + src/backend/commands/analyze.c | 1 + src/backend/commands/vacuumparallel.c | 1 + src/include/access/genam.h | 1 + 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index 2cd4e50aa61bc536e4da6e3325b659c9d75068e5..c5e443e81f4ee20240798f23ba02eb9cdc578a55 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -663,7 +663,7 @@ ginbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, * empty the pending list. This is still safe; concurrent inserters * cannot insert new tuples whose TIDs VACUUM needs us to remove. */ - ginInsertCleanup(&gvs.ginstate, !AmAutoVacuumWorkerProcess(), + ginInsertCleanup(&gvs.ginstate, !info->is_autovacuum, false, true, stats); /* we'll re-count the tuples each time */ @@ -775,7 +775,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) */ if (info->analyze_only) { - if (AmAutoVacuumWorkerProcess()) + if (info->is_autovacuum) { initGinState(&ginstate, index); ginInsertCleanup(&ginstate, false, true, true, stats); @@ -791,7 +791,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { stats = palloc0_object(IndexBulkDeleteResult); initGinState(&ginstate, index); - ginInsertCleanup(&ginstate, !AmAutoVacuumWorkerProcess(), + ginInsertCleanup(&ginstate, !info->is_autovacuum, false, true, stats); } diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 8e1f660bc2ff077001f197a4189029f41208ba43..997d84a77b35b7fab5b581d2f36aae7d24fc4b34 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -3042,6 +3042,7 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat, ivinfo.index = indrel; ivinfo.heaprel = vacrel->rel; ivinfo.analyze_only = false; + ivinfo.is_autovacuum = AmAutoVacuumWorkerProcess(); ivinfo.report_progress = false; ivinfo.estimated_count = true; ivinfo.message_level = DEBUG2; @@ -3092,6 +3093,7 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat, ivinfo.index = indrel; ivinfo.heaprel = vacrel->rel; ivinfo.analyze_only = false; + ivinfo.is_autovacuum = AmAutoVacuumWorkerProcess(); ivinfo.report_progress = false; ivinfo.estimated_count = estimated_count; ivinfo.message_level = DEBUG2; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 2a46cc4de19a2381bf58372f64ef6b1de04de407..4d232b85ad58d167b9cdee7430aeeea496e96f26 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3529,6 +3529,7 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) ivinfo.index = indexRelation; ivinfo.heaprel = heapRelation; ivinfo.analyze_only = false; + ivinfo.is_autovacuum = false; ivinfo.report_progress = true; ivinfo.estimated_count = true; ivinfo.message_level = DEBUG2; diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index c05f9f50e43da2b8b58610468131a4fb9350d2c4..4fea106bafd7ae4ea77548e3d7700f9f94651857 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -726,6 +726,7 @@ do_analyze_rel(Relation onerel, const VacuumParams *params, ivinfo.index = Irel[ind]; ivinfo.heaprel = onerel; ivinfo.analyze_only = true; + ivinfo.is_autovacuum = AmAutoVacuumWorkerProcess(); ivinfo.estimated_count = true; ivinfo.message_level = elevel; ivinfo.num_heap_tuples = onerel->rd_rel->reltuples; diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 767d162e5788dd009bdc7fae03f036ba4dade1cb..4532da60c842fbf622d5fd1c093e9d487872ec75 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -1087,6 +1087,7 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, ivinfo.index = indrel; ivinfo.heaprel = pvs->heaprel; ivinfo.analyze_only = false; + ivinfo.is_autovacuum = pvs->shared->is_autovacuum; ivinfo.report_progress = false; ivinfo.message_level = DEBUG2; ivinfo.estimated_count = pvs->shared->estimated_count; diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 72b256ecf4363b9499dcf9bf12aca9f6a5206a03..1bfdc1ef6b1ebd451f0276660b175112e52cf4b9 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -54,6 +54,7 @@ typedef struct IndexVacuumInfo Relation index; /* the index being vacuumed */ Relation heaprel; /* the heap relation the index belongs to */ bool analyze_only; /* ANALYZE (without any actual vacuum) */ + bool is_autovacuum; /* VACUUM/ANALYZE initiated by autovacuum */ bool report_progress; /* emit progress.h status reports */ bool estimated_count; /* num_heap_tuples is an estimate */ int message_level; /* ereport level for progress messages */ base-commit: 9e17d25e79d4756be08b4a5521b4b58450217137 -- 2.43.7