aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2012-06-26 16:16:52 -0400
committerRobert Haas <rhaas@postgresql.org>2012-06-27 08:34:28 -0400
commiteee5088e538be24f6c42e758ef27cecc2b2579f1 (patch)
tree2ee2d467ad4ebf9884960933ea5dd7e7530f7569
parent00e5844592a8c51ceee1682013b94ac50031a9ac (diff)
downloadpostgresql-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.sgml11
-rw-r--r--doc/src/sgml/high-availability.sgml16
-rw-r--r--src/backend/utils/adt/misc.c12
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);
}
/*