Hi,
AI review found a bug in parallel autovacuum (1ff3180ca01). I checked
it myself and it reproduces on HEAD and PG19. Patch with a test
attached.
A role with pg_signal_backend that is not a superuser gets "permission
denied to terminate process" [1] from DROP DATABASE WITH (FORCE) while
a parallel autovacuum on that database is in its index phase, which on
a large table is where the vacuum spends its time. The same role can
terminate the autovacuum worker itself, and DROP DATABASE without
FORCE succeeds with the same vacuum running.
Both the autovacuum worker and its parallel workers run as the
bootstrap superuser, so that is not what separates them.
TerminateOtherDBBackends() looks at the role a process published in
its PGPROC, and only the workers published one. The autovacuum worker
gets its user from InitializeSessionUserIdStandalone(), which sets
AuthenticatedUserId directly and never calls SetAuthenticatedUserId(),
so MyProc->roleId stays InvalidOid and superuser_arg() on it is false.
Its parallel workers take the same user through ParallelWorkerMain(),
which does call SetAuthenticatedUserId(), so they publish the
bootstrap superuser and the check refuses them.
A parallel worker of a VACUUM command is not affected, since its
leader is a user session and the worker publishes the same role as its
leader. Autovacuum is the only leader that publishes no role while its
workers publish one.
The fix treats a process whose lock group leader is an autovacuum
worker the way the autovacuum worker itself is treated. The patch adds
a test to the test_autovacuum module that fails with this error
without the fix.
[1]
ERROR: permission denied to terminate process
DETAIL: Only roles with the SUPERUSER attribute may terminate
processes of roles with the SUPERUSER attribute.
--
Bharath Rupireddy
Amazon Web Services: https://aws.amazon.com