PostgreSQL 中角色与 pg_terminate_backend and/or pg_cancel_backend 管理函数的关系

Relation between roles and pg_terminate_backend and/or pg_cancel_backend admin functions in PostgreSQL

考虑以下示例:

超级用户 admin 在 PostgreSQL 数据库中执行以下命令:

CREATE DATABASE admindb;
CREATE ROLE dbo WITH CREATEDB CREATEROLE;
GRANT ALL PRIVILEGES ON DATABASE admindb TO dbo WITH GRANT OPTION;
CREATE ROLE user1 WITH LOGIN PASSWORD 'user1pw';
GRANT dbo TO user1;
ALTER ROLE user1 SET ROLE dbo;

在下一步中,user1 执行以下操作:

psql -h 10.11.4.32 -d admindb -U user1
# creates a table in admindb database
CREATE TABLE test1 ( a INT, b INT);
# check pg_stat_activity

 datid | datname |  pid  | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | xact_start | query_start | state_change | wait_event_type | wait_event | state | backend_xid | backend_xmin | query
 17816 | admindb | 21314 |    17819 | user12  | psql             |             |                 |             |               |            |             |              |                 |            |       |             |          625 |<insufficient privilege>
(1 row)

请查看查询字段显示权限不足。

如果我在创建 user1 时没有 运行 ALTER ROLE user1 SET ROLE dbo,查询字段会正确显示它,如下所示。

 17816 | admindb | 18386 |    17819 | user12  | psql             | 192.168.0.12 |                 |       58794 | 2018-08-10 06:13:48.762903+00 | 2018-08-10 06:14:57.119916+00 | 2018-08-10 06:14:57.119916+00 | 2018-08-10 06:14:57.119917+00 |                 |            | active |             |          624 | select * from pg_stat_activity;
(1 row)

我想了解导致此行为的原因。

因此,如果 user1 运行 是一个长查询并尝试通过使用 psql 连接到 admindb 作为 user1 和 [=43 来取消它=]ning select pg_cancel_backend(pid),它因错误而失败。

ERROR:  must be a member of the role whose query is being canceled or member of pg_signal_backend

如果我删除 ALTER ROLE user1 SET ROLE dbo,则 user1 可以取消查询。

原因是 SET ROLE 在您连接后立即将您的活动用户上下文更改为 dbo,但您的“会话用户”仍然是 user1:

SELECT current_user, session_user;

 current_user | session_user 
--------------+--------------
 dbo          | user1
(1 row)

pg_stat_activity中你只能看到会话用户等于你当前活跃用户的会话,pg_cancel_backendpg_terminate_backend只允许你影响会话用户等于你当前活跃用户的后端用户。

您可以执行 RESET ROLE 恢复到 user1 并执行这些操作。