PostgreSQL 中的 ‘pg_stat_activity‘ 系统视图详解
本篇对PostgreSQL 中的pg_stat_activity系统视图进行一个非常详细和深入的讲解,并介绍其核心应用场景。
一、pg_stat_activity 是什么?
pg_stat_activity是 PostgreSQL 的一个系统视图(System View),它提供了对当前数据库服务器上所有正在运行的服务器进程的一瞥。每个连接到 PostgreSQL 服务器的客户端(包括后台进程)都会在其中对应一条记录。
你可以把它看作是数据库的“任务管理器”或“活动监视器”,是进行数据库监控、性能分析和故障排查的最重要工具之一。
二、视图字段详解(核心列说明)
查询SELECT * FROM pg_stat_activity;会返回很多列。以下是其中最常用和关键的列:
| 字段名 | 数据类型 | 描述 |
|---|---|---|
datid | Oid | 进程所连接的数据库的 OID。 |
datname | name | 进程所连接的数据库名。这是最常用的过滤字段。 |
pid | integer | 进程 ID。这是操作系统级别的进程 ID,是操作(如取消查询)的关键。 |
usesysid | Oid | 登录用户的 OID。 |
usename | name | 登录到此后端的用户名。 |
application_name | text | 应用程序名称。由客户端连接字符串中的application_name参数设置。常用于识别不同来源的连接(如“psql”, “pgAdmin”, “my_app_server_1”)。 |
client_addr | inet | 客户端的 IP 地址。如果通过 Unix domain socket 连接,则为 NULL。用于排查网络来源的问题。 |
client_hostname | text | 客户端的主机名(如果通过 IP 连接且启用了log_hostname)。 |
client_port | integer | 客户端用于通信的 TCP 端口号。 |
backend_start | timestamptz | 进程启动的时间(即客户端连接建立的时间)。 |
xact_start | timestamptz | 当前事务开始的时间。如果未在事务中,则为 NULL。 |
query_start | timestamptz | 当前正在执行的查询开始的时间。 |
state_change | timestamptz | 上次state改变的时间。 |
wait_event_type | text | 进程正在等待的事件类型(如Lock,LWLock,BufferPin)。这是分析瓶颈的关键。如果进程正在运行,则为 NULL。 |
wait_event | text | 等待事件的名称(如等待的锁类型)。与wait_event_type配合使用。 |
state | text | 当前后端的状态。这是极其重要的列: - active: 后端正在执行一个查询。- idle: 后端正在等待一个新的客户端命令。- idle in transaction: 后端在一个事务中,但当前没有执行查询。- idle in transaction (aborted): 后端在一个事务中,但事务中的一个语句出错了。- fastpath function call: 后端正在执行一个 fast-path 函数。- disabled: 如果 track_activities 被在这个后端禁用。 |
backend_xid | xid | 后端的顶级事务 ID(如果存在)。 |
backend_xmin | xid | 后端的xmin水平线,用于判断哪些行版本对此后端可见。 |
query | text | 该进程最近执行的查询文本。如果state是active,这就是当前正在运行的查询。如果track_activities被禁用,此值为 NULL。注意:超级用户可以看到所有查询,普通用户只能看到自己的查询。 |
query_id | bigint | 用于计算查询频率的哈希码(需要compute_query_id = on)。 |
三、核心应用场景和查询示例
1. 查看所有活动连接(最基本用法)
SELECT*FROMpg_stat_activity;2. 查看非空闲连接(聚焦正在工作的进程)
这是最常用的查询,过滤掉那些只是连着但没事干的连接。
SELECTdatname,usename,client_addr,application_name,state,query,query_start,now()-query_startASdurationFROMpg_stat_activityWHEREstate!='idle'ANDpid!=pg_backend_pid()-- 排除自己当前这个查询连接ORDERBYdurationDESC;3. 查找长时间运行的查询/事务(用于排查性能问题)
-- 查找运行超过 5 分钟的查询SELECTpid,usename,datname,now()-query_startASquery_duration,queryFROMpg_stat_activityWHEREstate='active'ANDnow()-query_start>interval'5 minutes'ORDERBYquery_durationDESC;-- 查找开启时间过长的事务(即使它现在没在执行查询)SELECTpid,usename,datname,now()-xact_startASxact_duration,state,queryFROMpg_stat_activityWHERExact_startISNOTNULLANDnow()-xact_start>interval'10 minutes'ORDERBYxact_durationDESC;4. 查找等待锁的进程(用于解决锁冲突)
SELECTpid,usename,datname,query,wait_event_type,wait_event,now()-query_startASwait_durationFROMpg_stat_activityWHEREwait_event_typeISNOTNULLANDwait_event_type='Lock'-- 聚焦在锁等待上ORDERBYwait_durationDESC;5. 按应用或用户统计连接数
-- 按应用统计SELECTapplication_name,count(*)FROMpg_stat_activityGROUPBYapplication_name;-- 按用户统计SELECTusename,count(*)FROMpg_stat_activityGROUPBYusename;-- 按数据库统计SELECTdatname,count(*)FROMpg_stat_activityGROUPBYdatname;6. 终止问题查询或连接(pg_terminate_backend)
当你发现一个异常查询(如长时间运行、死锁)时,可以用获取到的pid来终止它。
警告:这是强制杀死操作,可能会中断业务,请谨慎使用。
-- 取消一个查询(类似于 Ctrl+C),允许它自行回滚SELECTpg_cancel_backend(pid);-- 强制终止一个后端连接(类似于 kill -9),连接会立即断开,事务会回滚SELECTpg_terminate_backend(pid);-- 示例:终止所有连接到 'my_database' 的连接(常用于维护前踢出所有用户)SELECTpg_terminate_backend(pid)FROMpg_stat_activityWHEREdatname='my_database';7. 查找“僵尸”事务(Idle in Transaction)
这种状态的事务通常由应用程序bug引起(如开启了事务但未提交或回滚),它会持有锁、阻止VACUUM,是数据库的“大敌”。
SELECTpid,usename,datname,now()-xact_startASxact_duration,queryFROMpg_stat_activityWHEREstate='idle in transaction'ORDERBYxact_durationDESC;四、重要注意事项和最佳实践
- 权限: 普通用户只能看到自己会话的信息。超级用户可以看到所有会话的信息和查询。
query字段的性能:pg_stat_activity的query字段是text类型,可能很长。在生产环境频繁查询所有字段(尤其是SELECT *)可能会对性能有轻微影响。建议只选择你需要的列。pg_backend_pid(): 在编写管理脚本时,使用WHERE pid <> pg_backend_pid()可以排除掉你当前用于查询的管理连接自身,避免误杀自己。- 监控工具的基础: 几乎所有 PostgreSQL 监控工具(如 pgAdmin 的仪表盘、Zabbix、Prometheus + grafana 看板)其底层数据都来源于
pg_stat_activity和pg_stat_statements等系统视图。 - 结合其他视图: 为了更全面的分析,通常将
pg_stat_activity与pg_locks(查看锁详情)、pg_stat_statements(查看历史查询统计)等视图结合使用。
总之,pg_stat_activity是 PostgreSQL DBA 和开发者必须掌握的核心工具,熟练使用它能让你快速诊断数据库的实时状态、定位性能瓶颈和解决各种连接与锁相关问题。