Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)