From 513e0e3cc6c20c65cc0b1d7cca890eff22ef534a Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Fri, 9 Oct 2026 17:29:59 +0000 Subject: [PATCH v3 2/2] Add test for DROP DATABASE FORCE to terminate autovacuum parallel workers. This commit adds an injection point and a TAP test to check that DROP DATABASE FORCE run by a non-superuser terminates both an autovacuum worker and its parallel workers. Author: Bharath Rupireddy Reviewed-by: Masahiko Sawada Discussion: https://postgr.es/m/CALj2ACWK6PkOk5MTfibtJyTYpb%3DAq_8%3DYaexnPKhOj11bOCROQ%40mail.gmail.com Backpatch-through: 19 --- src/backend/commands/vacuumparallel.c | 4 ++ .../t/001_parallel_autovacuum.pl | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index 4e432c50d37..297aae60df6 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -47,6 +47,7 @@ #include "storage/bufmgr.h" #include "storage/proc.h" #include "tcop/tcopprot.h" +#include "utils/injection_point.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -1383,6 +1384,9 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) /* Register this worker for vacuum progress reporting */ pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM, shared->relid); + /* Used by tests to hold a worker while it is attached to its leader */ + INJECTION_POINT("parallel-vacuum-worker-start", NULL); + /* Process indexes to perform vacuum/cleanup */ parallel_vacuum_process_safe_indexes(&pvs); diff --git a/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl index 115f92a49e4..7312ae3dd4a 100644 --- a/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl +++ b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl @@ -254,5 +254,47 @@ $node->safe_psql('postgres', $node->safe_psql('postgres', "SELECT injection_points_detach('autovacuum-worker-cost-balanced')"); +# Test 4: +# Check that DROP DATABASE FORCE run by a non-superuser terminates both an +# autovacuum worker and its parallel workers. +$node->safe_psql( + 'postgres', qq{ + DROP TABLE test_autovac; + CREATE ROLE regress_dbowner LOGIN IN ROLE pg_signal_backend; + ALTER DATABASE regress_db2 OWNER TO regress_dbowner; + SELECT injection_points_attach('parallel-vacuum-worker-start', 'wait'); +}); + +$node->safe_psql( + 'regress_db2', qq{ + CREATE TABLE tbl_fddb (a int, b int) + WITH (autovacuum_parallel_workers = 1, autovacuum_vacuum_threshold = 1); + INSERT INTO tbl_fddb SELECT g, g FROM generate_series(1, 100) g; + CREATE INDEX tbl_fddb_a ON tbl_fddb (a); + CREATE INDEX tbl_fddb_b ON tbl_fddb (b); + DELETE FROM tbl_fddb; +}); + +$node->wait_for_event('parallel worker', 'parallel-vacuum-worker-start'); + +$log_offset = -s $node->logfile; + +my $psql_err = ''; +$node->psql( + 'postgres', + 'DROP DATABASE regress_db2 WITH (FORCE)', + connstr => $node->connstr('postgres') . ' user=regress_dbowner', + stderr => \$psql_err); +is($psql_err, '', 'no error from DROP DATABASE FORCE'); + +ok( $node->log_contains( + qr/FATAL: .*terminating background worker "parallel worker" due to administrator command/, + $log_offset), + 'DROP DATABASE FORCE terminates parallel autovacuum workers'); + +# No wakeup, the held worker is already gone. +$node->safe_psql('postgres', + "SELECT injection_points_detach('parallel-vacuum-worker-start')"); + $node->stop; done_testing(); -- 2.47.3