PostgreSQL 会话管理
当数据库发生持续的 CPU 使用率打高时,数据库中很可能正在跑一些大查询或者较复杂的 SQL,如果不及时处理很可能会影响到业务,此时我们需要通过查询会话找到 “罪魁祸首” 并 kill 掉它,然后拿着样本语句去优化。
在 MySQL 中可以通过 processlist 查询会话相关信息,那 PostgreSQL 也为运维人员通过会话统计视图 pg_stat_activity 本篇文章介绍视图各字段的含义及使用技巧。
1. 查询会话
因为表字段非常多,通过终端查询会重叠在一块,比较难看清,需要开启扩展显示,和 MySQL \G
类似。
postgres=# \x
Expanded display is on.
查询当前活跃的会话:
postgres=# select * from pg_stat_activity where state != 'idle';
-[ RECORD 1 ]----+-------------------------------------------------------
datid | 13593
datname | postgres
pid | 65695
usesysid | 10
usename | postgres
application_name | psql
client_addr |
client_hostname |
client_port | -1
backend_start | 2023-06-28 14:39:27.102519+08
xact_start | 2023-06-28 16:06:16.063186+08
query_start | 2023-06-28 16:06:16.063186+08
state_change | 2023-06-28 16:06:16.06322+08
wait_event_type |
wait_event |
state | active
backend_xid |
backend_xmin | 691
query | select * from pg_stat_activity where state != 'idle' ;
backend_type | client backend
2. 视图介绍
2.1 datid
这个后端连接到的数据库的 OID。
2.2 datname
这个后端连接到的数据库的名称。
2.3 pid
这个后端的进程 ID,kill 会话的时候需要用到它。
2.4 usesysid
登录到这个后端的用户的 OID。
2.5 usename
登录到这个后端的用户的名称。
2.6 application_name
连接到这个后端的应用的名称。
2.7 client_addr
连接到这个后端的客户端的 IP 地址。如果这个域为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程(如自动清理)。
2.8 client_hostname
已连接的客户端的主机名,由 client_addr 的反向 DNS 查找报告。这个域将只对 IP 连接非空,并且只有 log_hostname 被启用时才会非空。
2.9 client_port
客户端用以和这个后端通信的 TCP 端口号,如果使用 Unix 套接字则为 -1。
2.10 backend_start
这个进程被启动的时间,对客户端后端来说就是客户端连接到服务器的时间。
2.11 xact_start
这个进程的当前事务被启动的时间,如果没有活动事务则为空。如果当前查询是它的第一个事务,这一列等于 query_start。
2.12 query_start
当前活动查询被开始的时间,如果state不是active,这个域为上一个查询被开始的时间。
2.13 state_change
state 上一次被改变的时间。
2.14 wait_event_type
后端正在等待的事件类型,如果不存在则为 NULL。可能的值有:
LWLock:后端正在等待一个轻量级锁。每一个这样的锁保护着共享内存中的一个特殊数据结构。
Lock:后端正在等待一个重量级锁。重量级锁,也称为锁管理器锁或者简单锁,主要保护 SQL 可见的对象,例如表。
BufferPin:服务器进程正在等待访问一个数据缓冲区,而此时没有其他进程正在检查该缓冲区。如果另一个进程持有一个最终从要访问的缓冲区中读取数据的打开的游标,缓冲区 pin 等待可能会被拖延。
Activity:服务器进程处于闲置状态。这被用于在其主处理循环中等待活动的系统进程。wait_event将标识特定的等待点。
Extension:服务器进程正在一个扩展模块中等待活动。这一个分类被用于要跟踪自定义等待点的模块。
Client:服务器进程正在一个套接字上等待来自用户应用的某种活动,并且该服务器预期某种与其内部处理无关的事情发生。wait_event 将标识特定的等待点。
IPC:服务器进程正在等待来自服务器中另一个进程的某种活动。wait_event 将标识特定的等待点。
Timeout:服务器进程正在等待一次超时发生。wait_event 将标识特定的等待点。
IO:服务器进程正在等待一次 IO 完成。wait_event 将标识特定的等待点。
2.15 wait_event
如果后端当前正在等待,则是等待事件的 ,否则为 NULL。
2.16 state
这个后端的当前总体状态。可能的值是:
active:后端正在执行一个查询。
idle:此时为空闲状态,正在等待一个新的客户端命令。
idle in transaction:后端在一个事务中,但是当前没有正在执行一个查询。
idle in transaction (aborted):这个状态与 idle in transaction 相似,不过在该事务中的一个语句导致了一个错误。
fastpath function call:后端正在执行一个 fast-path 函数。
disabled:如果在这个后端中 track_activities 被禁用,则报告这个状态。
2.17 backend_xid
这个后端的顶层事务标识符(如果存在)。
2.18 backend_xmin
当前后端的 xmin 范围。
2.19 query
这个后端最近查询的文本。如果 state 为 active,这个域显示当前正在执行的查询。在所有其他状态下,它显示上一个被执行的查询。默认情况下,查询文本会被截断至 1024 个字符,这个值可以通过参数 track_activity_query_size 更改。
2.20 backend_type
当前后端的类型。可能的类型是 autovacuum launcher, autovacuum worker, logical replication launcher, logical replication worker, parallel worker, background writer, client backend, checkpointer, startup, walreceiver, walsender 以及 walwriter。 除此以外,由扩展注册的后台Worker可能有额外的类型。
3. 管理会话
3.1 查询会话
通过下方查询可查看会话:
#查看活跃会话
select * from pg_stat_activity where state != 'idle' ;
#查看包含在事物内的会话
select * from pg_stat_activity where state like '%idle%transaction%';
#查看耗时1s以上的活跃会话
select * from pg_stat_activity where state<>'idle' and now()-query_start > interval '1 s' order by query_start ;
3.2 杀掉会话
通过下方命令可以从 pg 的后台杀死这个进程,从而释放出宝贵的连接资源。
select pg_terminate_backend($pid);
ERROR:The connection to the server was lost
SELECT pg_cancel_backend($pid);