diff options
author | Robert Haas <rhaas@postgresql.org> | 2012-06-26 16:16:52 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2012-06-27 08:34:28 -0400 |
commit | eee5088e538be24f6c42e758ef27cecc2b2579f1 (patch) | |
tree | 2ee2d467ad4ebf9884960933ea5dd7e7530f7569 | |
parent | 00e5844592a8c51ceee1682013b94ac50031a9ac (diff) | |
download | postgresql-eee5088e538be24f6c42e758ef27cecc2b2579f1.tar.gz postgresql-eee5088e538be24f6c42e758ef27cecc2b2579f1.zip |
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.
-rw-r--r-- | doc/src/sgml/func.sgml | 11 | ||||
-rw-r--r-- | doc/src/sgml/high-availability.sgml | 16 | ||||
-rw-r--r-- | src/backend/utils/adt/misc.c | 12 |
3 files changed, 23 insertions, 16 deletions
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index de13c7c4761..d3ed2397fb0 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -14392,7 +14392,11 @@ SELECT set_config('log_statement_stats', 'off', false); <literal><function>pg_terminate_backend(<parameter>pid</parameter> <type>int</>)</function></literal> </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> </tbody> </tgroup> @@ -14413,9 +14417,8 @@ SELECT set_config('log_statement_stats', 'off', false); <command>postgres</command> processes on the server (using <application>ps</> on Unix or the <application>Task Manager</> on <productname>Windows</>). - For the less restrictive <function>pg_cancel_backend</>, the role of an - active backend can be found from - the <structfield>usename</structfield> column of the + The role of an active backend can be found from the + <structfield>usename</structfield> column of the <structname>pg_stat_activity</structname> view. </para> diff --git a/doc/src/sgml/high-availability.sgml b/doc/src/sgml/high-availability.sgml index c268bfb8d3f..4eb37d24610 100644 --- a/doc/src/sgml/high-availability.sgml +++ b/doc/src/sgml/high-availability.sgml @@ -1969,13 +1969,15 @@ LOG: database system is ready to accept read only connections </para> <para> - <function>pg_cancel_backend()</> will work on user backends, but not the - Startup process, which performs recovery. <structname>pg_stat_activity</structname> does not - show an entry for the Startup process, nor do recovering transactions - show as active. As a result, <structname>pg_prepared_xacts</structname> 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. + <function>pg_cancel_backend()</> + and <function>pg_terminate_backend()</> will work on user backends, + but not the Startup process, which performs + recovery. <structname>pg_stat_activity</structname> does not show an + entry for the Startup process, nor do recovering transactions show + as active. As a result, <structname>pg_prepared_xacts</structname> + 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> diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 96e692766bf..f3c7860f0c3 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -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 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, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to terminate other server processes"), - errhint("You can cancel your own processes with pg_cancel_backend()."))); + (errmsg("must be superuser or have the same role to terminate backends running in other server processes")))); - PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM) == SIGNAL_BACKEND_SUCCESS); + PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); } /* |