首页 > 解决方案 > 如何终止 Google Cloud SQL for PostgreSQL 中的会话?

问题描述

由于 PostgreSQL 的 Google Cloud SQL 没有给我们超级用户(甚至 postgres 用户),我看不到其他会话正在从 pg_stat_activity 运行什么查询,也无法在需要时终止其他会话。

例如:

postgres@testdb=> select pg_terminate_backend(1584);
ERROR:  42501: must be a member of the role whose process is being terminated or member of pg_signal_backend
LOCATION:  pg_terminate_backend, misc.c:319
Time: 23.800 ms

如果没有真正的超级用户访问权限,我们如何在 Cloud SQL PostgreSQL 实例中执行这些操作?只有 cloudsqladmin 帐户是超级用户,而 AFAIK 我不能这样:

postgres@testdb=> \dg
                                            List of roles
     Role name     |                         Attributes                         |      Member of
-------------------+------------------------------------------------------------+---------------------
 cloudsqladmin     | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 cloudsqlagent     | Create role, Create DB                                     | {cloudsqlsuperuser}
 cloudsqlreplica   | Replication                                                | {}
 cloudsqlsuperuser | Create role, Create DB                                     | {}
 don               | Create role, Create DB                                     | {cloudsqlsuperuser}
 postgres          | Create role, Create DB                                     | {cloudsqlsuperuser}

postgres@testdb=> set role cloudsqladmin;
ERROR:  42501: permission denied to set role "cloudsqladmin"
LOCATION:  call_string_check_hook, guc.c:9803
Time: 25.293 ms

FWIW,如果您以该会话的用户身份登录,则可以终止会话。用户可以终止他们的任何会话,标准 PostgreSQL 的东西。

postgres@postgres=> select pg_terminate_backend(23644);
ERROR:  42501: must be a member of the role whose process is being terminated or member of pg_signal_backend
LOCATION:  pg_terminate_backend, misc.c:319

don@postgres=> select pg_terminate_backend(23644);
 pg_terminate_backend
----------------------
 t
(1 row)

标签: postgresqlgoogle-cloud-sql

解决方案


pg_terminate_backend说:

pg_terminate_backend(pid int) - 终止后端。如果调用角色是其后端被终止或调用角色已被授予的角色的成员,这也是允许的pg_signal_backend,但是只有超级用户可以终止超级用户后端。

当您是 Google 的成员cloudsqlsuperuser(默认为gcloud sql users create)时,您可以授予自己:

GRANT pg_signal_backend TO myuser;

然后您可以终止除超级用户之外的任何会话:

SELECT pg_terminate_backend(pid), * FROM pg_stat_activity
WHERE usename = 'rogue_user' AND pid <> pg_backend_pid();

pg_signal_backend是在 v9.6 中引入的 - 正是 Google Cloud 上的版本!

另一种方法是在other角色内能够终止会话me

GRANT other TO me;

推荐阅读