Hi,

On Thu, Apr 2, 2026 at 6:16 AM Masahiko Sawada <[email protected]> wrote:
>
> Thank you for updating the patch! I found a bug in the following code:
>
> @@ -457,6 +534,9 @@ parallel_vacuum_end(ParallelVacuumState *pvs,
> IndexBulkDeleteResult **istats)
>   DestroyParallelContext(pvs->pcxt);
>   ExitParallelMode();
>
> + if (AmAutoVacuumWorkerProcess())
> + pv_shared_cost_params = NULL;
> +
>
> If an autovacuum worker raises an error during parallel vacuum, it
> doesn't pv_shared_cost_params. Then, if it doesn't use parallel vacuum
> on the next table to vacuum, it would end up with SEGV as it attempts
> to propagate the vacuum delay parameters.

Ouch. Indeed, I did not foresee this.
Thank you for noticing it!

I think we should add some cleanup for autovacuum near the ParallelContext
cleanup, since they are interconnected. I also want to return our tests that
are triggering ERROR/PANIC in the leader worker in order to check whether all
resources are released. I hope I will be able to get to that by tomorrow
evening.

--
Best regards,
Daniil Davydov
From b649988718442143256eae59f29b770d08f1fc97 Mon Sep 17 00:00:00 2001
From: Daniil Davidov <[email protected]>
Date: Thu, 2 Apr 2026 22:08:06 +0700
Subject: [PATCH] Make sure that all recourses have been released in parallel
 autovacuum

---
 src/backend/access/transam/parallel.c |  7 +++++++
 src/backend/commands/vacuumparallel.c | 15 +++++++++++++++
 src/include/access/parallel.h         |  3 +++
 3 files changed, 25 insertions(+)

diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index ab1dfb30e73..81bca48bcfa 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -1292,6 +1292,13 @@ AtEOXact_Parallel(bool isCommit)
 			elog(WARNING, "leaked parallel context");
 		DestroyParallelContext(pcxt);
 	}
+
+	/*
+	 * Parallel autovacuum may have resources that depend on ParallelContext,
+	 * but are local to vacuumparallel.c
+	 */
+	if (AmAutoVacuumWorkerProcess())
+		AtEOXact_ParallelAutovacuum(isCommit);
 }
 
 /*
diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c
index bac3bd28214..68d4a25528d 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -541,6 +541,21 @@ parallel_vacuum_end(ParallelVacuumState *pvs, IndexBulkDeleteResult **istats)
 	pfree(pvs);
 }
 
+/*
+ * End-of-transaction cleanup for parallel autovacuum.
+ */
+void
+AtEOXact_ParallelAutovacuum(bool isCommit)
+{
+	if (pv_shared_cost_params == NULL)
+		return;
+
+	if (isCommit)
+		elog(WARNING, "leaked parallel autovacuum state");
+
+	pv_shared_cost_params = NULL;
+}
+
 /*
  * Returns the dead items space and dead items information.
  */
diff --git a/src/include/access/parallel.h b/src/include/access/parallel.h
index 60f857675e0..553273b1529 100644
--- a/src/include/access/parallel.h
+++ b/src/include/access/parallel.h
@@ -80,4 +80,7 @@ extern void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end);
 
 extern void ParallelWorkerMain(Datum main_arg);
 
+/* vacuumparallel.c */
+extern void AtEOXact_ParallelAutovacuum(bool isCommit);
+
 #endif							/* PARALLEL_H */
-- 
2.43.0

Reply via email to