Allow pg_terminate_backend() to be used on backends with matching role.

A similar change was made previously for pg_cancel_backend, so now it
all matches again.

Dan Farina, reviewed by Fujii Masao, Noah Misch, and Jeff Davis,
with slight kibitzing on the doc changes by me.
This commit is contained in:
Robert Haas 2012-06-26 16:16:52 -04:00
parent b79ab00144
commit c60ca19de9
3 changed files with 23 additions and 16 deletions

View File

@ -14393,7 +14393,11 @@ SELECT set_config('log_statement_stats', 'off', false);
<literal><function>pg_terminate_backend(<parameter>pid</parameter> <type>int</>)</function></literal> <literal><function>pg_terminate_backend(<parameter>pid</parameter> <type>int</>)</function></literal>
</entry> </entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>Terminate a backend</entry> <entry>Terminate a backend. You can execute this against
another backend that has exactly the same role as the user
calling the function. In all other cases, you must be a
superuser.
</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
@ -14414,9 +14418,8 @@ SELECT set_config('log_statement_stats', 'off', false);
<command>postgres</command> processes on the server (using <command>postgres</command> processes on the server (using
<application>ps</> on Unix or the <application>Task <application>ps</> on Unix or the <application>Task
Manager</> on <productname>Windows</>). Manager</> on <productname>Windows</>).
For the less restrictive <function>pg_cancel_backend</>, the role of an The role of an active backend can be found from the
active backend can be found from <structfield>usename</structfield> column of the
the <structfield>usename</structfield> column of the
<structname>pg_stat_activity</structname> view. <structname>pg_stat_activity</structname> view.
</para> </para>

View File

@ -1969,13 +1969,15 @@ LOG: database system is ready to accept read only connections
</para> </para>
<para> <para>
<function>pg_cancel_backend()</> will work on user backends, but not the <function>pg_cancel_backend()</>
Startup process, which performs recovery. <structname>pg_stat_activity</structname> does not and <function>pg_terminate_backend()</> will work on user backends,
show an entry for the Startup process, nor do recovering transactions but not the Startup process, which performs
show as active. As a result, <structname>pg_prepared_xacts</structname> is always empty during recovery. <structname>pg_stat_activity</structname> does not show an
recovery. If you wish to resolve in-doubt prepared transactions, entry for the Startup process, nor do recovering transactions show
view <literal>pg_prepared_xacts</> on the primary and issue commands to as active. As a result, <structname>pg_prepared_xacts</structname>
resolve transactions there. is always empty during recovery. If you wish to resolve in-doubt
prepared transactions, view <literal>pg_prepared_xacts</> on the
primary and issue commands to resolve transactions there.
</para> </para>
<para> <para>

View File

@ -162,18 +162,20 @@ pg_cancel_backend(PG_FUNCTION_ARGS)
} }
/* /*
* Signal to terminate a backend process. Only allowed by superuser. * Signal to terminate a backend process. This is allowed if you are superuser
* or have the same role as the process being terminated.
*/ */
Datum Datum
pg_terminate_backend(PG_FUNCTION_ARGS) pg_terminate_backend(PG_FUNCTION_ARGS)
{ {
if (!superuser()) int r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM);
if (r == SIGNAL_BACKEND_NOPERMISSION)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to terminate other server processes"), (errmsg("must be superuser or have the same role to terminate backends running in other server processes"))));
errhint("You can cancel your own processes with pg_cancel_backend().")));
PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM) == SIGNAL_BACKEND_SUCCESS); PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
} }
/* /*