Skip to content

Commit 372700c

Browse files
committed
Fix documentation about DROP DATABASE FORCE process termination rights.
Specifically, it terminates a background worker even if the caller couldn't terminate the background worker with pg_terminate_backend(). Commit 3a9b18b neglected to update this. Back-patch to v13, which introduced DROP DATABASE FORCE. Reviewed by Amit Kapila. Reported by Kirill Reshke. Discussion: https://postgr.es/m/20240429212756.60.nmisch@google.com
1 parent a3e6c6f commit 372700c

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

doc/src/sgml/ref/drop_database.sgml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,14 @@ DROP DATABASE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [
7979
It doesn't terminate if prepared transactions, active logical replication
8080
slots or subscriptions are present in the target database.
8181
</para>
82+
<!-- not mentioning exception for autovacuum workers, since those are an
83+
implementation detail and the exception is not specific to FORCE -->
8284
<para>
83-
This will fail if the current user has no permissions to terminate other
84-
connections. Required permissions are the same as with
85-
<literal>pg_terminate_backend</literal>, described in
86-
<xref linkend="functions-admin-signal"/>. This will also fail if we
87-
are not able to terminate connections.
85+
This terminates background worker connections and connections that the
86+
current user has permission to terminate
87+
with <function>pg_terminate_backend</function>, described in
88+
<xref linkend="functions-admin-signal"/>. If connections would remain,
89+
this command will fail.
8890
</para>
8991
</listitem>
9092
</varlistentry>

src/backend/storage/ipc/procarray.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3808,8 +3808,8 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
38083808
* The current backend is always ignored; it is caller's responsibility to
38093809
* check whether the current backend uses the given DB, if it's important.
38103810
*
3811-
* It doesn't allow to terminate the connections even if there is a one
3812-
* backend with the prepared transaction in the target database.
3811+
* If the target database has a prepared transaction or permissions checks
3812+
* fail for a connection, this fails without terminating anything.
38133813
*/
38143814
void
38153815
TerminateOtherDBBackends(Oid databaseId)
@@ -3854,14 +3854,19 @@ TerminateOtherDBBackends(Oid databaseId)
38543854
ListCell *lc;
38553855

38563856
/*
3857-
* Check whether we have the necessary rights to terminate other
3858-
* sessions. We don't terminate any session until we ensure that we
3859-
* have rights on all the sessions to be terminated. These checks are
3860-
* the same as we do in pg_terminate_backend.
3857+
* Permissions checks relax the pg_terminate_backend checks in two
3858+
* ways, both by omitting the !OidIsValid(proc->roleId) check:
38613859
*
3862-
* In this case we don't raise some warnings - like "PID %d is not a
3863-
* PostgreSQL server process", because for us already finished session
3864-
* is not a problem.
3860+
* - Accept terminating autovacuum workers, since DROP DATABASE
3861+
* without FORCE terminates them.
3862+
*
3863+
* - Accept terminating bgworkers. For bgworker authors, it's
3864+
* convenient to be able to recommend FORCE if a worker is blocking
3865+
* DROP DATABASE unexpectedly.
3866+
*
3867+
* Unlike pg_terminate_backend, we don't raise some warnings - like
3868+
* "PID %d is not a PostgreSQL server process", because for us already
3869+
* finished session is not a problem.
38653870
*/
38663871
foreach(lc, pids)
38673872
{
@@ -3870,15 +3875,13 @@ TerminateOtherDBBackends(Oid databaseId)
38703875

38713876
if (proc != NULL)
38723877
{
3873-
/* Only allow superusers to signal superuser-owned backends. */
38743878
if (superuser_arg(proc->roleId) && !superuser())
38753879
ereport(ERROR,
38763880
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
38773881
errmsg("permission denied to terminate process"),
38783882
errdetail("Only roles with the %s attribute may terminate processes of roles with the %s attribute.",
38793883
"SUPERUSER", "SUPERUSER")));
38803884

3881-
/* Users can signal backends they have role membership in. */
38823885
if (!has_privs_of_role(GetUserId(), proc->roleId) &&
38833886
!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
38843887
ereport(ERROR,

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