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 3a9b18b3095366cd0c4305441d426d04572d88c1 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
This commit is contained in:
parent
b284513752
commit
01e98e0cdd
@ -79,12 +79,14 @@ DROP DATABASE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [
|
|||||||
It doesn't terminate if prepared transactions, active logical replication
|
It doesn't terminate if prepared transactions, active logical replication
|
||||||
slots or subscriptions are present in the target database.
|
slots or subscriptions are present in the target database.
|
||||||
</para>
|
</para>
|
||||||
|
<!-- not mentioning exception for autovacuum workers, since those are an
|
||||||
|
implementation detail and the exception is not specific to FORCE -->
|
||||||
<para>
|
<para>
|
||||||
This will fail if the current user has no permissions to terminate other
|
This terminates background worker connections and connections that the
|
||||||
connections. Required permissions are the same as with
|
current user has permission to terminate
|
||||||
<literal>pg_terminate_backend</literal>, described in
|
with <function>pg_terminate_backend</function>, described in
|
||||||
<xref linkend="functions-admin-signal"/>. This will also fail if we
|
<xref linkend="functions-admin-signal"/>. If connections would remain,
|
||||||
are not able to terminate connections.
|
this command will fail.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -3855,8 +3855,8 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
|
|||||||
* The current backend is always ignored; it is caller's responsibility to
|
* The current backend is always ignored; it is caller's responsibility to
|
||||||
* check whether the current backend uses the given DB, if it's important.
|
* check whether the current backend uses the given DB, if it's important.
|
||||||
*
|
*
|
||||||
* It doesn't allow to terminate the connections even if there is a one
|
* If the target database has a prepared transaction or permissions checks
|
||||||
* backend with the prepared transaction in the target database.
|
* fail for a connection, this fails without terminating anything.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TerminateOtherDBBackends(Oid databaseId)
|
TerminateOtherDBBackends(Oid databaseId)
|
||||||
@ -3901,14 +3901,19 @@ TerminateOtherDBBackends(Oid databaseId)
|
|||||||
ListCell *lc;
|
ListCell *lc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether we have the necessary rights to terminate other
|
* Permissions checks relax the pg_terminate_backend checks in two
|
||||||
* sessions. We don't terminate any session until we ensure that we
|
* ways, both by omitting the !OidIsValid(proc->roleId) check:
|
||||||
* have rights on all the sessions to be terminated. These checks are
|
|
||||||
* the same as we do in pg_terminate_backend.
|
|
||||||
*
|
*
|
||||||
* In this case we don't raise some warnings - like "PID %d is not a
|
* - Accept terminating autovacuum workers, since DROP DATABASE
|
||||||
* PostgreSQL server process", because for us already finished session
|
* without FORCE terminates them.
|
||||||
* is not a problem.
|
*
|
||||||
|
* - Accept terminating bgworkers. For bgworker authors, it's
|
||||||
|
* convenient to be able to recommend FORCE if a worker is blocking
|
||||||
|
* DROP DATABASE unexpectedly.
|
||||||
|
*
|
||||||
|
* Unlike pg_terminate_backend, we don't raise some warnings - like
|
||||||
|
* "PID %d is not a PostgreSQL server process", because for us already
|
||||||
|
* finished session is not a problem.
|
||||||
*/
|
*/
|
||||||
foreach(lc, pids)
|
foreach(lc, pids)
|
||||||
{
|
{
|
||||||
@ -3917,13 +3922,11 @@ TerminateOtherDBBackends(Oid databaseId)
|
|||||||
|
|
||||||
if (proc != NULL)
|
if (proc != NULL)
|
||||||
{
|
{
|
||||||
/* Only allow superusers to signal superuser-owned backends. */
|
|
||||||
if (superuser_arg(proc->roleId) && !superuser())
|
if (superuser_arg(proc->roleId) && !superuser())
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
errmsg("must be a superuser to terminate superuser process")));
|
errmsg("must be a superuser to terminate superuser process")));
|
||||||
|
|
||||||
/* Users can signal backends they have role membership in. */
|
|
||||||
if (!has_privs_of_role(GetUserId(), proc->roleId) &&
|
if (!has_privs_of_role(GetUserId(), proc->roleId) &&
|
||||||
!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
|
!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user