diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 595523e3eb..4f539428e2 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -14393,7 +14393,11 @@ SELECT set_config('log_statement_stats', 'off', false); pg_terminate_backend(pid int) boolean - Terminate a backend + 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. + @@ -14414,9 +14418,8 @@ SELECT set_config('log_statement_stats', 'off', false); postgres processes on the server (using ps on Unix or the Task Manager on Windows). - For the less restrictive pg_cancel_backend, the role of an - active backend can be found from - the usename column of the + The role of an active backend can be found from the + usename column of the pg_stat_activity view. diff --git a/doc/src/sgml/high-availability.sgml b/doc/src/sgml/high-availability.sgml index c268bfb8d3..4eb37d2461 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 - pg_cancel_backend() will work on user backends, but not the - Startup process, which performs recovery. pg_stat_activity does not - show an entry for the Startup process, nor do recovering transactions - show as active. As a result, pg_prepared_xacts is always empty during - recovery. If you wish to resolve in-doubt prepared transactions, - view pg_prepared_xacts on the primary and issue commands to - resolve transactions there. + pg_cancel_backend() + and pg_terminate_backend() will work on user backends, + but not the Startup process, which performs + recovery. pg_stat_activity does not show an + entry for the Startup process, nor do recovering transactions show + as active. As a result, pg_prepared_xacts + is always empty during recovery. If you wish to resolve in-doubt + prepared transactions, view pg_prepared_xacts on the + primary and issue commands to resolve transactions there. diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 96e692766b..f3c7860f0c 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); } /*