Skip to content

Commit d2b7488

Browse files
committed
Add tap test for pg_signal_autovacuum role
This commit provides testig coverage for ccd3802, checking that a role granted pg_signal_autovacuum_worker is able to stop a vacuum worker. An injection point with a wait is placed at the beginning of autovacuum worker startup to make sure that a worker is still alive when sending and processing the signal sent. Author: Anthony Leung, Michael Paquier, Kirill Reshke Reviewed-by: Andrey Borodin, Nathan Bossart Discussion: https://postgr.es/m/CALdSSPiQPuuQpOkF7x0g2QkA5eE-3xXt7hiJFvShV1bHKDvf8w@mail.gmail.com
1 parent 47ecbfd commit d2b7488

File tree

3 files changed

+104
-1
lines changed

3 files changed

+104
-1
lines changed

src/backend/postmaster/autovacuum.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
#include "utils/fmgroids.h"
101101
#include "utils/fmgrprotos.h"
102102
#include "utils/guc_hooks.h"
103+
#include "utils/injection_point.h"
103104
#include "utils/lsyscache.h"
104105
#include "utils/memutils.h"
105106
#include "utils/ps_status.h"
@@ -1902,6 +1903,12 @@ do_autovacuum(void)
19021903
/* Start a transaction so our commands have one to play into. */
19031904
StartTransactionCommand();
19041905

1906+
/*
1907+
* This injection point is put in a transaction block to work with a wait
1908+
* that uses a condition variable.
1909+
*/
1910+
INJECTION_POINT("autovacuum-worker-start");
1911+
19051912
/*
19061913
* Compute the multixact age for which freezing is urgent. This is
19071914
* normally autovacuum_multixact_freeze_max_age, but may be less if we are

src/test/modules/test_misc/meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ tests += {
1313
't/002_tablespace.pl',
1414
't/003_check_guc.pl',
1515
't/004_io_direct.pl',
16-
't/005_timeouts.pl'
16+
't/005_timeouts.pl',
17+
't/006_signal_autovacuum.pl',
1718
],
1819
},
1920
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Copyright (c) 2024, PostgreSQL Global Development Group
2+
3+
# Test signaling autovacuum worker with pg_signal_autovacuum_worker.
4+
#
5+
# Only roles with privileges of pg_signal_autovacuum_worker are allowed to
6+
# signal autovacuum workers. This test uses an injection point located
7+
# at the beginning of the autovacuum worker startup.
8+
9+
use strict;
10+
use warnings;
11+
use PostgreSQL::Test::Cluster;
12+
use Test::More;
13+
14+
if ($ENV{enable_injection_points} ne 'yes')
15+
{
16+
plan skip_all => 'Injection points not supported by this build';
17+
}
18+
19+
# Initialize postgres
20+
my $psql_err = '';
21+
my $psql_out = '';
22+
my $node = PostgreSQL::Test::Cluster->new('node');
23+
$node->init;
24+
25+
# This ensures a quick worker spawn.
26+
$node->append_conf('postgresql.conf', 'autovacuum_naptime = 1');
27+
$node->start;
28+
$node->safe_psql('postgres', 'CREATE EXTENSION injection_points;');
29+
30+
$node->safe_psql(
31+
'postgres', qq(
32+
CREATE ROLE regress_regular_role;
33+
CREATE ROLE regress_worker_role;
34+
GRANT pg_signal_autovacuum_worker TO regress_worker_role;
35+
));
36+
37+
# From this point, autovacuum worker will wait at startup.
38+
$node->safe_psql('postgres',
39+
"SELECT injection_points_attach('autovacuum-worker-start', 'wait');");
40+
41+
# Accelerate worker creation in case we reach this point before the naptime
42+
# ends.
43+
$node->reload();
44+
45+
# Wait until an autovacuum worker starts.
46+
$node->wait_for_event('autovacuum worker', 'autovacuum-worker-start');
47+
48+
# And grab one of them.
49+
my $av_pid = $node->safe_psql(
50+
'postgres', qq(
51+
SELECT pid FROM pg_stat_activity WHERE backend_type = 'autovacuum worker' AND wait_event = 'autovacuum-worker-start' LIMIT 1;
52+
));
53+
54+
# Regular role cannot terminate autovacuum worker.
55+
my $terminate_with_no_pg_signal_av = $node->psql(
56+
'postgres', qq(
57+
SET ROLE regress_regular_role;
58+
SELECT pg_terminate_backend('$av_pid');
59+
),
60+
stdout => \$psql_out,
61+
stderr => \$psql_err);
62+
63+
like(
64+
$psql_err,
65+
qr/ERROR: permission denied to terminate process\nDETAIL: Only roles with privileges of the "pg_signal_autovacuum_worker" role may terminate autovacuum workers./,
66+
"autovacuum worker not signaled with regular role");
67+
68+
my $offset = -s $node->logfile;
69+
70+
# Role with pg_signal_autovacuum can terminate autovacuum worker.
71+
my $terminate_with_pg_signal_av = $node->psql(
72+
'postgres', qq(
73+
SET ROLE regress_worker_role;
74+
SELECT pg_terminate_backend('$av_pid');
75+
),
76+
stdout => \$psql_out,
77+
stderr => \$psql_err);
78+
79+
# Wait for the autovacuum worker to exit before scanning the logs.
80+
$node->poll_query_until('postgres',
81+
"SELECT count(*) = 0 FROM pg_stat_activity "
82+
. "WHERE pid = '$av_pid' AND backend_type = 'autovacuum worker';");
83+
84+
# Check that the primary server logs a FATAL indicating that autovacuum
85+
# is terminated.
86+
ok( $node->log_contains(
87+
qr/FATAL: terminating autovacuum process due to administrator command/,
88+
$offset),
89+
"autovacuum worker signaled with pg_signal_autovacuum_worker granted");
90+
91+
# Release injection point.
92+
$node->safe_psql('postgres',
93+
"SELECT injection_points_detach('autovacuum-worker-start');");
94+
95+
done_testing();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy