pg_stat_activity是系统视图,显示数据库中当前正在发生的事情。
对于较新的 pgs,它相当宽(我写这篇文章时有 22 列)。而且,这一切意味着什么并不总是很明显。所以让我们试着弄清楚。
使用用户测试连接到数据库depesz并获得:
$ select * from pg_stat_activity ;
datid │ datname │ pid │ leader_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_id │ query │ backend_type
────────┼──────────┼────────┼────────────┼──────────┼─────────┼──────────────────┼─────────────┼─────────────────┼─────────────┼───────────────────────────────┼───────────────────────────────┼───────────────────────────────┼─────────────────────────────┼─────────────────┼────────────┼────────┼─────────────┼──────────────┼─────────────────────┼──────────────────────────────────┼────────────────
[null] │ [null] │ 87714 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ <insufficient privilege> │ [null]
[null] │ [null] │ 87716 │ [null] │ 10 │ pgdba │ │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ <insufficient privilege> │ [null]
325115 │ depesz │ 849586 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ <insufficient privilege> │ [null]
325115 │ depesz │ 848113 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ 16596 │ [null] │ [null] │ <insufficient privilege> │ [null]
325115 │ depesz │ 848261 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ 16593 │ [null] │ <insufficient privilege> │ [null]
5 │ postgres │ 848535 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ 16593 │ [null] │ [null] │ <insufficient privilege> │ [null]
5 │ postgres │ 848405 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ 16593 │ [null] │ <insufficient privilege> │ [null]
325115 │ depesz │ 848805 │ [null] │ 16390 │ test │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:43:41.338899+02 │ 2022-07-04 16:47:16.559599+02 │ 2022-07-04 16:47:16.559599+02 │ 2022-07-04 16:47:16.5596+02 │ [null] │ [null] │ active │ [null] │ 16593 │ -907669364431849768 │ select * from pg_stat_activity ; │ client backend
[null] │ [null] │ 87711 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ <insufficient privilege> │ [null]
[null] │ [null] │ 87715 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ <insufficient privilege> │ [null]
[null] │ [null] │ 87710 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ <insufficient privilege> │ [null]
[null] │ [null] │ 87713 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ [null] │ <insufficient privilege> │ [null]
(12 rows)
我注意到的第一件事是查询列中的值:
$ select * from pg_stat_activity where pid = 848805 \gx
─[ RECORD 1 ]────┬───────────────────────────────────────────────────
datid │ 325115
datname │ depesz
pid │ 848805
leader_pid │ [null]
usesysid │ 16390
usename │ test
application_name │ psql
client_addr │ [null]
client_hostname │ [null]
client_port │ -1
backend_start │ 2022-07-04 16:43:41.338899+02
xact_start │ 2022-07-04 16:49:18.495575+02
query_start │ 2022-07-04 16:49:18.495575+02
state_change │ 2022-07-04 16:49:18.495577+02
wait_event_type │ [null]
wait_event │ [null]
state │ active
backend_xid │ [null]
backend_xmin │ 16593
query_id │ 8210364456846404087
query │ select * from pg_stat_activity where pid = 848805
backend_type │ client backend
切换到超级用户后,我可以看到:
$ select * from pg_stat_activity;
datid │ datname │ pid │ leader_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_id │ query │ backend_type
────────┼──────────┼────────┼────────────┼──────────┼─────────┼──────────────────┼─────────────┼─────────────────┼─────────────┼───────────────────────────────┼───────────────────────────────┼───────────────────────────────┼───────────────────────────────┼─────────────────┼─────────────────────┼─────────────────────┼─────────────┼──────────────┼─────────────────────┼───────────────────────────────────────────────────────────────────────┼──────────────────────────────
[null] │ [null] │ 87714 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.737082+02 │ [null] │ [null] │ [null] │ Activity │ AutoVacuumMain │ [null] │ [null] │ [null] │ [null] │ │ autovacuum launcher
[null] │ [null] │ 87716 │ [null] │ 10 │ pgdba │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.737313+02 │ [null] │ [null] │ [null] │ Activity │ LogicalLauncherMain │ [null] │ [null] │ [null] │ [null] │ │ logical replication launcher
325115 │ depesz │ 849586 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:45:03.983256+02 │ [null] │ 2022-07-04 16:45:54.774817+02 │ 2022-07-04 16:45:54.775426+02 │ Client │ ClientRead │ idle │ [null] │ [null] │ 328096568509443406 │ SELECT n.nspname AS "Name", ↵│ client backend
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner", ↵│
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ pg_catalog.array_to_string(n.nspacl, E'\n') AS "Access privileges",↵│
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ pg_catalog.obj_description(n.oid, 'pg_namespace') AS "Description" ↵│
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ FROM pg_catalog.pg_namespace n ↵│
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' ↵│
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ORDER BY 1; │
325115 │ depesz │ 848113 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:42:47.613258+02 │ 2022-07-04 16:43:32.90074+02 │ 2022-07-04 16:43:35.176834+02 │ 2022-07-04 16:43:35.177334+02 │ Client │ ClientRead │ idle in transaction │ 16596 │ [null] │ -58199854079439753 │ drop table q; │ client backend
325115 │ depesz │ 848261 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:42:54.562032+02 │ 2022-07-04 16:43:37.768588+02 │ 2022-07-04 16:43:37.768588+02 │ 2022-07-04 16:43:37.76859+02 │ Lock │ relation │ active │ [null] │ 16593 │ [null] │ select * from q; │ client backend
5 │ postgres │ 848535 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:43:03.427086+02 │ 2022-07-04 16:43:10.942546+02 │ 2022-07-04 16:43:12.494412+02 │ 2022-07-04 16:43:12.497506+02 │ Client │ ClientRead │ idle in transaction │ 16593 │ [null] │ 389562163604003053 │ drop table z; │ client backend
5 │ postgres │ 848405 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:42:59.671318+02 │ 2022-07-04 16:43:15.250683+02 │ 2022-07-04 16:43:15.250683+02 │ 2022-07-04 16:43:15.250685+02 │ Lock │ relation │ active │ [null] │ 16593 │ [null] │ select * from z; │ client backend
325115 │ depesz │ 852004 │ [null] │ 10 │ pgdba │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:50:25.426408+02 │ 2022-07-04 16:50:45.614384+02 │ 2022-07-04 16:50:45.614384+02 │ 2022-07-04 16:50:45.614385+02 │ [null] │ [null] │ active │ [null] │ 16593 │ -907669364431849768 │ select * from pg_stat_activity │ client backend
[null] │ [null] │ 87711 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.731409+02 │ [null] │ [null] │ [null] │ Activity │ BgWriterHibernate │ [null] │ [null] │ [null] │ [null] │ │ background writer
[null] │ [null] │ 87715 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.737179+02 │ [null] │ [null] │ [null] │ Activity │ ArchiverMain │ [null] │ [null] │ [null] │ [null] │ │ archiver
[null] │ [null] │ 87710 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.731313+02 │ [null] │ [null] │ [null] │ Activity │ CheckpointerMain │ [null] │ [null] │ [null] │ [null] │ │ checkpointer
[null] │ [null] │ 87713 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.736982+02 │ [null] │ [null] │ [null] │ Activity │ WalWriterMain │ [null] │ [null] │ [null] │ [null] │ │ walwriter
(12 rows)
好的。所有的列。但对他们真的意味着什么?
首先——这个视图为每个后端进程显示一行。大多数这些,在普通系统中(这只是我桌面上的测试数据库)将是来自应用程序的连接。但不是所有的。
每个进程都有它的 PID(进程号),您始终可以使用以下方法从 DB 连接中检查您自己的 PID:
$ select pg_backend_pid();
pg_backend_pid
────────────────
852004
(1 row)
这与系统可见的 PID 相同,例如,在使用ps命令时:
=$ ps uw -p 852004
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
pgdba 852004 0.0 0.0 216984 19516 ? Ss 16:50 0:00 postgres: pgdba depesz [local] idle
所以,让我们深入挖掘。我们将从……从头开始。最后一列是 backend_type:
$ select pid, backend_type from pg_stat_activity order by backend_type, pid;
pid │ backend_type
────────┼──────────────────────────────
87715 │ archiver
87714 │ autovacuum launcher
87711 │ background writer
87710 │ checkpointer
848261 │ client backend
848405 │ client backend
848535 │ client backend
849586 │ client backend
852004 │ client backend
853274 │ client backend
87716 │ logical replication launcher
87713 │ walwriter
(12 rows)
“客户端后端”基本上是您与应用程序的正常连接。所有其他连接都是“做事”的特殊进程:
- archiver – 运行 archive_command(或在较新的 pgs 中等效)
- autovacuum 启动器——当需要对某些东西进行 vacuum /分析时,启动 autovacuum workers
- 后台写入器——在后台将数据写入表/索引
- checkpointer 处理检查点——基本上是不时地将所有修改的数据写入表/索引文件
- 逻辑复制启动器——管理与逻辑复制相关的进程
- walwriter – 将数据更改写入 WAL
除了这些,您还可以看到:
- autovacuum worker – 实际上为 autovacuum 做一些 vacuum /分析工作
- 逻辑复制工作者——处理逻辑复制
- 并行工作者 - 由客户端后端启动的特殊后端,其中查询正在并行处理
- 启动 - 从某个地方应用 WAL,这是负责恢复和流/wal 复制的过程
- walreceiver – 在流复制设置中从源接收 wal 流
- walsender – 通过流将 wal 发送到某个副本
如果您使用专门的扩展,您还可以看到一些其他类型。
知道了这一点,让我们回顾一下我们的数据,它的另一个子集:
$ select * from pg_stat_activity where backend_type <> 'client backend';
datid │ datname │ pid │ leader_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_id │ query │ backend_type
────────┼─────────┼───────┼────────────┼──────────┼─────────┼──────────────────┼─────────────┼─────────────────┼─────────────┼───────────────────────────────┼────────────┼─────────────┼──────────────┼─────────────────┼─────────────────────┼────────┼─────────────┼──────────────┼──────────┼───────┼──────────────────────────────
[null] │ [null] │ 87714 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.737082+02 │ [null] │ [null] │ [null] │ Activity │ AutoVacuumMain │ [null] │ [null] │ [null] │ [null] │ │ autovacuum launcher
[null] │ [null] │ 87716 │ [null] │ 10 │ pgdba │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.737313+02 │ [null] │ [null] │ [null] │ Activity │ LogicalLauncherMain │ [null] │ [null] │ [null] │ [null] │ │ logical replication launcher
[null] │ [null] │ 87711 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.731409+02 │ [null] │ [null] │ [null] │ Activity │ BgWriterHibernate │ [null] │ [null] │ [null] │ [null] │ │ background writer
[null] │ [null] │ 87715 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.737179+02 │ [null] │ [null] │ [null] │ Activity │ ArchiverMain │ [null] │ [null] │ [null] │ [null] │ │ archiver
[null] │ [null] │ 87710 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.731313+02 │ [null] │ [null] │ [null] │ Activity │ CheckpointerMain │ [null] │ [null] │ [null] │ [null] │ │ checkpointer
[null] │ [null] │ 87713 │ [null] │ [null] │ [null] │ │ [null] │ [null] │ [null] │ 2022-07-01 10:55:08.736982+02 │ [null] │ [null] │ [null] │ Activity │ WalWriterMain │ [null] │ [null] │ [null] │ [null] │ │ walwriter
(6 rows)
请注意,大多数列都是空的,因为——嗯,这些是没有连接到任何特定数据库的进程,也没有使用任何特定用户(除了逻辑复制启动器)。通常你并不真正关心他们。
对于其他后端(在我的情况下,只有普通的客户端后端):
$ select * from pg_stat_activity where backend_type = 'client backend';
datid │ datname │ pid │ leader_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_id │ query │ backend_type
────────┼──────────┼────────┼────────────┼──────────┼─────────┼──────────────────┼─────────────┼─────────────────┼─────────────┼───────────────────────────────┼───────────────────────────────┼───────────────────────────────┼───────────────────────────────┼─────────────────┼────────────┼─────────────────────┼─────────────┼──────────────┼──────────────────────┼───────────────────────────────────────────────────────────────────────┼────────────────
5 │ postgres │ 848405 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:42:59.671318+02 │ 2022-07-04 16:43:15.250683+02 │ 2022-07-04 16:43:15.250683+02 │ 2022-07-04 16:43:15.250685+02 │ Lock │ relation │ active │ [null] │ 16593 │ [null] │ select * from z; │ client backend
5 │ postgres │ 848535 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:43:03.427086+02 │ 2022-07-04 16:43:10.942546+02 │ 2022-07-04 16:43:12.494412+02 │ 2022-07-04 16:43:12.497506+02 │ Client │ ClientRead │ idle in transaction │ 16593 │ [null] │ 389562163604003053 │ drop table z; │ client backend
325115 │ depesz │ 848261 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:42:54.562032+02 │ 2022-07-04 16:53:24.693972+02 │ 2022-07-04 16:53:24.693972+02 │ 2022-07-04 16:53:24.693974+02 │ Lock │ relation │ active │ [null] │ 16593 │ [null] │ select * from q; │ client backend
325115 │ depesz │ 853274 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:53:19.46231+02 │ 2022-07-04 16:53:21.765739+02 │ 2022-07-04 16:53:23.106893+02 │ 2022-07-04 16:53:23.107714+02 │ Client │ ClientRead │ idle in transaction │ 16597 │ [null] │ -58199854079439753 │ drop table q; │ client backend
325115 │ depesz │ 864116 │ [null] │ 16384 │ depesz │ psql │ [null] │ [null] │ -1 │ 2022-07-04 17:10:43.001571+02 │ [null] │ 2022-07-04 17:10:44.682067+02 │ 2022-07-04 17:10:44.682396+02 │ Client │ ClientRead │ idle │ [null] │ [null] │ -2698492627503961632 │ select 1; │ client backend
325115 │ depesz │ 852004 │ [null] │ 10 │ pgdba │ psql │ [null] │ [null] │ -1 │ 2022-07-04 16:50:25.426408+02 │ 2022-07-04 17:10:54.757781+02 │ 2022-07-04 17:10:54.757781+02 │ 2022-07-04 17:10:54.757783+02 │ [null] │ [null] │ active │ [null] │ 16593 │ -2404663320170207359 │ select * from pg_stat_activity where backend_type = 'client backend' │ client backend
(6 rows)
datid 和 datname 基本上只是这个后端连接到哪个数据库的信息。您可以看到这些值在 pg_database 表中显示为 oid 和 datname:
$ select oid, datname from pg_database where datname in ('postgres', 'depesz');
oid │ datname
────────┼──────────
5 │ postgres
325115 │ depesz
(2 rows)
这向我们展示了一件重要的事情——pg_stat_activity 包含有关所有数据库的信息。不仅是您连接的那个。如果您在某些数据库中寻找问题的根源,并且您不断看到与其他数据库的连接使信息变得模糊,这有时可能会出现问题。
因此,您可能希望将where datname = current_database()添加到您的查询中。
接下来是pid,我解释过,然后是leader_pid。这通常是NULL。如果您有并行化查询,则它不为空,在这种情况下,并行工作者后端将在启动它们的后端的leader_pid列 pid 中(真实的原始数据库连接),如下所示:
pid │ leader_pid │ backend_type │ query
────────┼────────────┼─────────────────┼───────────────────────────────────────────
867808 │ [null] │ client backend │ select sum(length(p::text)) from plans p;
868383 │ 867808 │ parallel worker │ select sum(length(p::text)) from plans p;
868384 │ 867808 │ parallel worker │ select sum(length(p::text)) from plans p;
(3 rows)
这表明与 pid 867808 的连接启动了一个查询,Pg 决定启动两个额外的工作程序以更快地计算它。一旦此查询结束,这些后端 worker 就会消失。
接下来在 pg_stat_activity 我们有用户信息:usesysid 和 usename。就像数据库名称/ID 一样,这些是关于用户的相同信息,您可以在select usesysid, usename from pg_user中看到这些信息。
接下来是application_name。这是应用程序提供的名称,您可以随时更改它:
$ select application_name from pg_stat_activity where pid = pg_backend_pid();
application_name
──────────────────
psql
(1 row)
$ set application_name = 'magic';
SET
$ select application_name from pg_stat_activity where pid = pg_backend_pid();
application_name
──────────────────
magic
(1 row)
我假设在大多数语言中,您可以使用数据库连接参数设置应用程序名称,或者,如果您的应用程序使用标准 libpq,您可以使用环境变量 PGAPPNAME:
=$ psql -c 'select application_name from pg_stat_activity where pid = pg_backend_pid()'
application_name
------------------
psql
(1 row)
=$ PGAPPNAME=testing psql -c 'select application_name from pg_stat_activity where pid = pg_backend_pid()'
application_name
------------------
testing
(1 row)
当涉及到调试问题时,这个东西(application_name)绝对是惊人的。如果您不使用它 - 开始。
pg_stat_activity 中的下一件事是 3 列,它们告诉我们用户从哪里连接:
1、client_addr – 客户端机器的 ip
2、client_hostname – 客户端机器的主机名
3、client_port – 连接的源端口
问题是 PostgreSQL 可以使用两种方式连接:
- TCP/IP 连接——基本上是通过网络,来自另一台服务器,或者,有时,来自使用localhost作为服务器的同一台机器
- UNIX 套接字 - 可用于连接的特殊神奇“文件”,仅在本地。运行 psql 或其他 CLI 应用程序时的默认设置。
对于 UNIX 套接字——client_addr 和 client_hostname 为 NULL,端口设置为 -1,但如果我使用 TCP/IP 连接:
=$ psql -h localhost -c 'select client_addr, client_hostname, client_port from pg_stat_activity where pid = pg_backend_pid()'
client_addr │ client_hostname │ client_port
─────────────┼─────────────────┼─────────────
127.0.0.1 │ [null] │ 43574
(1 row)
client_hostname 为空,因为要使其可见,我必须打开log_hostname配置变量,我不这样做,因为它不是必需的(对我来说)。
接下来是 4 列,其中之一是最常被误解的:
- backend_start – 当这个后端启动时 – 基本上,在客户端后端的情况下 – 当客户端连接时。
- xact_start – 当前活动事务何时开始。应该理解的是,即使您没有执行BEGIN – 每个查询本身都在事务中,所以只有当您不在事务中并且您当前没有处理任何事情时,它才会为空。
- query_start – 上次开始的查询是什么时候开始的。此查询可能已经结束。但是 query_start 仍然存在——这是经常被误解的一件事。
- state_change – 后端状态最后一次更改是什么时候。这可能是在后端空闲的情况下——最后一个查询何时结束——因为状态从活动变为空闲。
query_start 的问题在于人们似乎认为now() – query_start的意思是:查询运行了多长时间(到目前为止)。如果后端当前正在处理某些事情(状态 = ‘活动’),它有点像。但是如果它是空闲的,那么这个计算就没有任何意义了,因为它现在什么都做不了。让我们看一个例子:
$ select pid, now() - query_start as duration, query_start, state_change, state, query from pg_stat_activity where backend_type = 'client backend';
pid │ duration │ query_start │ state_change │ state │ query
────────┼─────────────────┼───────────────────────────────┼───────────────────────────────┼─────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
864116 │ 00:26:46.690661 │ 2022-07-04 17:10:44.682067+02 │ 2022-07-04 17:10:44.682396+02 │ idle │ select 1;
853274 │ 00:44:08.265835 │ 2022-07-04 16:53:23.106893+02 │ 2022-07-04 16:53:23.107714+02 │ idle in transaction │ drop table q;
848261 │ 00:44:06.678756 │ 2022-07-04 16:53:24.693972+02 │ 2022-07-04 16:53:24.693974+02 │ active │ select * from q;
848535 │ 00:54:18.878316 │ 2022-07-04 16:43:12.494412+02 │ 2022-07-04 16:43:12.497506+02 │ idle in transaction │ drop table z;
848405 │ 00:54:16.122045 │ 2022-07-04 16:43:15.250683+02 │ 2022-07-04 16:43:15.250685+02 │ active │ select * from z;
868019 │ 00:00:00.709748 │ 2022-07-04 17:37:30.66298+02 │ 2022-07-04 17:37:30.663767+02 │ idle │ select pid, leader_pid, backend_type, query from pg_stat_activity where datname = 'depesz_explain' and pid <> pg_backend_pid()
852004 │ 00:00:00 │ 2022-07-04 17:37:31.372728+02 │ 2022-07-04 17:37:31.372729+02 │ active │ select pid, now() - query_start as duration, query_start, state_change, state, query from pg_stat_activity where backend_type = 'client backend';
867808 │ 00:18:16.976686 │ 2022-07-04 17:19:14.396042+02 │ 2022-07-04 17:19:37.187507+02 │ idle │ select sum(length(p::text)) from plans p;
(8 rows)
请注意,只有 3 个后端在做某事(pids 848261、848405、852004)。对他们来说,持续时间栏是有意义的。对于所有其他人 - 它没有。
那么为什么’查询’列中有东西?答案很简单——这是此后端中最后处理的查询。它可能是当前的(在 state = ‘active’ 的情况下),但对于 idle/idle-in-transaction - 这只是从query_start 开始并在state_change完成的最后一个查询。
这个问题被报告为“长时间运行的琐碎查询,例如’select 1’或’commit’,经常如此,这就是我写这篇博文的基本原因。
因此,虽然还有其他状态,但最常见的 3 个状态是:
- active - 后端正在积极处理查询(它可能被锁定,但它正在尝试这样做)
- idle - 后端完成了所有之前给定的工作,并且没有做任何事情。它不在事务中,它不持有任何锁,它只是存在。
- idle in transaction —— 至少从2008 年开始就是我存在的祸根。这意味着后端已经开始事务,可能有一些查询在其中运行,但目前它没有做任何事情。空转。但是在事务中,这意味着在该事务中的所有查询期间获得的所有锁仍然被持有,并且可以锁定其他后端进行生产性工作
这给我们留下了中间的五列来解释:
pid │ wait_event_type │ wait_event │ backend_xid │ backend_xmin │ query_id │ query
────────┼─────────────────┼────────────┼─────────────┼──────────────┼──────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
864116 │ Client │ ClientRead │ [null] │ [null] │ -2698492627503961632 │ select 1;
853274 │ Client │ ClientRead │ 16597 │ [null] │ -58199854079439753 │ drop table q;
848261 │ Lock │ relation │ [null] │ 16593 │ [null] │ select * from q;
848535 │ Client │ ClientRead │ 16593 │ [null] │ 389562163604003053 │ drop table z;
848405 │ Lock │ relation │ [null] │ 16593 │ [null] │ select * from z;
868019 │ Client │ ClientRead │ [null] │ [null] │ 1114137780797701598 │ select pid, leader_pid, backend_type, query from pg_stat_activity where datname = 'depesz_explain' and pid <> pg_backend_pid()
852004 │ [null] │ [null] │ [null] │ 16593 │ 7635051274713358230 │ select pid, wait_event_type, wait_event, backend_xid, backend_xmin, query_id, query from pg_stat_activity where backend_type = 'client backend';
867808 │ Client │ ClientRead │ [null] │ [null] │ -2698492627503961632 │ select 2;
(8 rows)
意思是:
- wait_event_type - 基本上是后端当前正在等待的事件类别。它可能是许多事情之一,但最有趣/最常见的是:
- 客户端 - 后端正在等待客户端接收数据或发送新查询,它没有被锁定 —— 客户端必须做一些事情
- 锁定 - 后端实际上被锁定在某些东西上(很可能被另一个后端锁定)
- NULL - 后端没有等待 - 它正在处理某些事情(当前查询)
- IO - 后端正在等待磁盘做任何需要做的事情(读/写的东西)
- wait_event – 有关它可能是什么的更详细信息。例如,在 wait_event_type = ‘Lock’ 的情况下,您可以有11 个不同的 wait_events,每个都是不同类型的锁。
- backend_xid – 后端当前处理的事务的事务 ID,如果它在内部事务中
- backend_xmin – 与“此后端可以看到哪些数据更改”相关的内部数据
- query_id – 查询的数字哈希,删除所有参数。请注意 pids 864116 和 867808 的 query_id 是相同的,尽管查询是不同的——这是因为参数无关紧要,所以“选择 1”可以像“选择 2”一样对待
我希望这将有助于消除关于阅读 pg_stat_activity 并将 query_start 理解为当前处理的查询的无条件开始的困惑。
原文标题:Understanding pg_stat_activity
原文地址:https://www.depesz.com/2022/07/05/understanding-pg_stat_activity/




