查看和终止 PostgreSQL 连接会话

文章目录

        利用视图 pg_stat_activity 查看连接会话
        通过操作系统命令查看连接会话
        利用 pg_cancel_backend() 终止正在运行的语句
        通过操作系统命令终止正在运行的语句
        利用 pg_terminate_backend() 终止连接会话
        通过操作系统命令终止连接会话

今天给大家介绍一下如何如何查看和终止 PostgreSQL 的连接会话。

在 PostgreSQL 中,配置参数 max_connections 决定了数据库的并发连接上限,默认值为 100:

postgres=> show max_connections;
 max_connections
-----------------
 100
(1 row)

这个数值还包括了预留给 superuser 的一些连接,具体数量由参数 superuser_reserved_connections 决定:

postgres=> show superuser_reserved_connections;
 superuser_reserved_connections
--------------------------------
 3
(1 row)

也就是说,当连接数到达 max_connections - superuser_reserved_connections 时,只有超级用户才能建立新的数据库连接;普通用户连接时将会返回错误信息“FATAL: sorry, too many clients already.”或者“FATAL: remaining connection slots are reserved for non-replication superuser connections”。当我们遇到这种连接数过多的错误,或者由于其他原因需要找出目前存在哪些客户端的连接时,可以采用以下方法。
利用视图 pg_stat_activity 查看连接会话

PostgreSQL 动态统计视图 pg_stat_activity 中的每一行代表了一个后台进程,包含了该进程当前活动相关的信息。

postgres=> select pid,
       datname as database_name,
       usename as user_name,
       application_name,
       client_addr,
       backend_start,
       state,
       state_change,
       wait_event_type,
       wait_event,
       query,
       backend_type
from pg_catalog.pg_stat_activity;
pid  |database_name|user_name|application_name                         |client_addr |backend_start      |state |state_change       |wait_event_type|wait_event         |query                                                                                                                                                                                                                                                          |backend_type                |
-----|-------------|---------|-----------------------------------------|------------|-------------------|------|-------------------|---------------|-------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|
 1677|             |         |                                         |            |2020-07-06 09:29:33|      |                   |Activity       |AutoVacuumMain     |                                                                                                                                                                                                                                                               |autovacuum launcher         |
 1679|             |postgres |                                         |            |2020-07-06 09:29:33|      |                   |Activity       |LogicalLauncherMain|                                                                                                                                                                                                                                                               |logical replication launcher|
23483|hrdb         |postgres |DBeaver 7.1.2 - Main <hrdb>              |192.168.56.1|2020-07-08 08:09:58|idle  |2020-07-08 08:09:58|Client         |ClientRead         |SHOW search_path                                                                                                                                                                                                                                               |client backend              |
23484|hrdb         |postgres |DBeaver 7.1.2 - Metadata <hrdb>          |192.168.56.1|2020-07-08 08:09:58|idle  |2020-07-08 08:09:58|Client         |ClientRead         |SELECT t.oid,t.*,c.relkind,format_type(nullif(t.typbasetype, 0), t.typtypmod) as base_type_name¶FROM pg_catalog.pg_type t¶LEFT OUTER JOIN pg_class c ON c.oid=t.typrelid¶WHERE typnamespace=$1 ¶ORDER by t.oid                                                 |client backend              |
23486|pagila       |postgres |DBeaver 7.1.2 - SQLEditor <Script-13.sql>|192.168.56.1|2020-07-08 08:09:58|active|2020-07-08 08:10:30|               |                   |select pid,¶       datname as database_name,¶       usename as user_name,¶       application_name,¶       client_addr,¶       backend_start,¶       state,¶       state_change,¶       wait_event_type,¶       wait_event,¶       query,¶       backend_type¶fr|client backend              |
23487|pagila       |postgres |DBeaver 7.1.2 - Main <pagila>            |192.168.56.1|2020-07-08 08:09:58|idle  |2020-07-08 08:09:58|Client         |ClientRead         |SHOW search_path                                                                                                                                                                                                                                               |client backend              |
23488|pagila       |postgres |DBeaver 7.1.2 - Metadata <pagila>        |192.168.56.1|2020-07-08 08:09:58|idle  |2020-07-08 08:10:00|Client         |ClientRead         |SELECT t.oid,t.*,c.relkind,format_type(nullif(t.typbasetype, 0), t.typtypmod) as base_type_name FROM pg_catalog.pg_type t¶LEFT OUTER JOIN pg_class c ON c.oid=t.typrelid¶WHERE t.oid=$1                                                                        |client backend              |
 1675|             |         |                                         |            |2020-07-06 09:29:33|      |                   |Activity       |BgWriterHibernate  |                                                                                                                                                                                                                                                               |background writer           |
 1674|             |         |                                         |            |2020-07-06 09:29:33|      |                   |Activity       |CheckpointerMain   |                                                                                                                                                                                                                                                               |checkpointer                |
 1676|             |         |                                         |            |2020-07-06 09:29:33|      |                   |Activity       |WalWriterMain      |                                                                                                                                                                                                                                                               |walwriter                   |

查询结果不仅返回了客户端连接对应的服务器进程,也包括 PostgreSQL 服务器的各种守护进程。其中,

    pid 代表了后台进程的 id;
    datname 是进程连接的数据库,对于后台守护进程显示为空;
    usename 是连接数据库使用的用户名,对于后台守护进程显示为空;
    application_name 是连接数据库的应用程序,对于后台守护进程显示为空;
    client_addr 是客户端的 IP 地址,对于后台守护进程或者通过 Unix 套接字连接的进程显示为空;
    backend_start 是进程启动的时间点,对于客户端的后台进程是连接服务器的时间点;
    state 代表了进程当前的状态,可能的取值包括 active、idle、idle in transaction、idle in transaction (aborted)、fastpath function call 以及 disabled;
    state_change 是最后一次状态的修改时间;
    wait_event_type 表示进程正在等待的事件类型,如果没有等待显示为空;可能的取值包括 LWLock、Lock、BufferPin、Activity、Extension、Client、IPC、Timeout 以及 IO;
    wait_event 表示进程正在等待的事件名称,如果没有等待显示为空;
    query 是进程最后一次执行的查询语句。对于 active 状态,显示正在执行的查询;其他状态显示上一次执行的查询;
    backend_type 是进程的类型。

    📝等待事件 wait_event 和进程状态 state 是相互独立的。如果进程处于 active 状态,可能正在等待某个事件,也可能没有等待事件如果状态为 active 并且 wait_event 不为空,意味着正在执行的查询被其他进程阻塞。

视图 pg_stat_activity 中还包含了更多的字段,具体可以参考官方文档。
通过操作系统命令查看连接会话

对于 Linux 操作系统,我们也可以使用ps命令查看 PostgreSQL 后台进程:

ps -ef|grep 'postgres'|grep -v 'grep'
postgres  1258     1  0 Jul06 ?        00:00:09 /usr/pgsql-12/bin/postmaster -D /var/lib/pgsql/12/data/
postgres  1335  1258  0 Jul06 ?        00:00:00 postgres: logger   
postgres  1674  1258  0 Jul06 ?        00:00:00 postgres: checkpointer   
postgres  1675  1258  0 Jul06 ?        00:00:05 postgres: background writer   
postgres  1676  1258  0 Jul06 ?        00:00:05 postgres: walwriter   
postgres  1677  1258  0 Jul06 ?        00:00:05 postgres: autovacuum launcher   
postgres  1678  1258  0 Jul06 ?        00:00:11 postgres: stats collector   
postgres  1679  1258  0 Jul06 ?        00:00:00 postgres: logical replication launcher   
postgres 23483  1258  0 08:09 ?        00:00:00 postgres: postgres hrdb 192.168.56.1(63614) idle
postgres 23484  1258  0 08:09 ?        00:00:00 postgres: postgres hrdb 192.168.56.1(63615) idle
postgres 23486  1258  0 08:09 ?        00:00:00 postgres: postgres pagila 192.168.56.1(63616) idle
postgres 23487  1258  0 08:09 ?        00:00:00 postgres: postgres pagila 192.168.56.1(63617) idle
postgres 23488  1258  0 08:09 ?        00:00:00 postgres: postgres pagila 192.168.56.1(63618) idle

其中,1258 是 postmaster 主进程;其他进程都是它的子进程。这种方式显示的进程信息相对简单一些。
利用 pg_cancel_backend() 终止正在运行的语句

函数 pg_cancel_backend(pid) 可以用于取消进程正在执行的查询,其中 pid 就是进程 id,可以通过上面的 pg_stat_activity 视图进行查看。

我们新建一个数据库连接,并且执行以下语句:

-- 新建数据库连接
postgres=> select pg_sleep(60);

pg_sleep 函数可以将当前会话的进程暂停指定时间,这里是 60 秒。

然后在另一个会话中终止该进程正在执行的查询:

-- 另一个连接会话
postgres=> select pid,
       query
from pg_catalog.pg_stat_activity
where wait_event = 'PgSleep';
pid  |query               |
-----|--------------------|
28582|select pg_sleep(60);|

postgres=> select pg_cancel_backend(28582);
pg_cancel_backend|
-----------------|
true             |

   

函数 pg_cancel_backend() 执行成功后返回 true,此时第一个连接会话将会返回以下错误:

ERROR:  canceling statement due to user request

   

虽然当前查询被终止,但是连接会话仍然存在,可以继续执行其他查询。
通过操作系统命令终止正在运行的语句

pg_cancel_backend() 函数实际上是给进程发送了一个 SIGINT 信号。因此,对于 Linux 操作系统,我们也可以使用kill命令终止终止正在运行的语句:

kill -2 pid

其中,-2 代表了 SIGINT 信号;pid 是进程 id。
利用 pg_terminate_backend() 终止连接会话

有时候 pg_cancel_backend() 需要等待很长时间才能终止正在执行的查询,为此我们也可以使用 pg_terminate_backend(pid) 函数强制终止整个连接进程。

例如,我们可以使用以下语句终止连接进程(28582):

-- 另一个连接会话

更多请见:http://www.mark-to-win.com/tutorial/51614.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值