pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
PostgreSQL 的统计收集器 是一个支持收集和报告服务器活动 信息的子系统。目前,收集器可以按磁盘块 和单行两种方式统计对表 和索引的访问。它还支持 确定其他服务器进程当前正在执行的 确切查询。
由于统计收集会给查询执行增加一些 开销,系统可以配置为收集或不收集 信息。这由通常在 postgresql.conf 中设置的配置变量控制 (设置配置变量的详情见 第 3.4 节)。
要让统计收集器能够启动,必须把变量 STATS_START_COLLECTOR 设为 true。这是默认且被推荐的设置, 但如果你对统计信息不感兴趣并想榨干 每一点开销,也可以把它关掉。(不过节省的 开销可能很小。)注意这个选项 在服务器运行期间不能更改。
变量 STATS_COMMAND_STRING、 STATS_BLOCK_LEVEL 和 STATS_ROW_LEVEL 控制实际发送给收集器的信息量, 从而决定运行时开销 的大小。 它们分别决定一个服务器进程是否 把自己的当前命令串、磁盘块级访问统计和 行级访问统计发送给收集器。通常这些变量 在 postgresql.conf 中设置, 从而作用于所有服务器 进程,但可以用 SET 命令在单个 服务器进程中开关它们。(为防止 普通用户向管理员隐藏自己的活动,只有 超级用户才被允许用 SET 更改这些 变量。)
由于变量 STATS_COMMAND_STRING、 STATS_BLOCK_LEVEL 和 STATS_ROW_LEVEL 默认为 false,默认配置下实际上不收集任何 统计信息!必须先打开其中一个或多个, 统计显示函数才会给出有用的 结果。
有若干预定义视图可用来显示统计收集的 结果。另外,也可以 用底层的统计函数构建自定义视图。
用统计信息监控当前活动时,重要的一点是 要认识到这些信息不会即时更新。 每个服务器进程在等待下一条 客户端命令之前传输新的访问计数;因此仍在进行中的查询 不会影响显示的总量。此外,收集器本身 每最多 PGSTAT_STAT_INTERVAL(默认 500 毫秒)才发出一次新的总量。因此显示的总量落后于 实际活动。
另一个要点是,当服务器进程被要求显示 这些统计信息中的任何一种时,它会先取回 收集器进程发出的最新总量,然后 在当前事务结束之前继续使用这一 快照用于所有统计视图和函数。 因此,只要继续当前事务,统计信息看起来就 不会变化。这是一个特性而不是缺陷,因为它 允许你对统计信息执行多个 查询并关联结果,而不必担心数字在 你手下变化。但如果想让每个查询都看到 新结果,请务必在任何事务 块之外执行查询。
表 10.1. 标准统计视图
| 视图名 | 描述 |
|---|---|
pg_stat_activity |
每个服务器进程一行,显示进程 PID、数据库、 用户和当前查询。当前查询列只有 超级用户可用;对其他用户读取为 NULL。 (注意,由于收集器的报告延迟, 当前查询只对长时间运行的查询是最新的。) |
pg_stat_database |
每个数据库一行,显示活动后端数、 该数据库中已提交和已回滚的事务总数、 读取的磁盘块总数,以及缓冲区命中总数 (即因在缓冲缓存中找到块而避免的 块读请求数)。 |
pg_stat_all_tables |
当前数据库中的每个表:顺序扫描 和索引扫描的总次数、每种扫描返回的 元组总数,以及元组插入、更新 和删除的总数。 |
pg_stat_sys_tables |
与 pg_stat_all_tables 相同,但只显示系统表。 |
pg_stat_user_tables |
与 pg_stat_all_tables 相同,但只显示用户表。 |
pg_stat_all_indexes |
当前数据库中的每个索引:使用该 索引的索引扫描总次数、读取的索引 元组数,以及成功取出的堆元组数。(当 存在指向过期堆元组的索引条目时,后者 可能更少。) |
pg_stat_sys_indexes |
与 pg_stat_all_indexes 相同,但只显示系统表上的 索引。 |
pg_stat_user_indexes |
与 pg_stat_all_indexes 相同,但只显示用户表上的 索引。 |
pg_statio_all_tables |
当前数据库中的每个表:从该表读取的 磁盘块总数、缓冲区命中数、该表所有索引的 磁盘块读取数和缓冲区命中数、该表辅助 TOAST 表(若有)的磁盘块读取数和缓冲区 命中数,以及 TOAST 表索引的磁盘块读取数 和缓冲区命中数。 |
pg_statio_sys_tables |
与 pg_statio_all_tables 相同,但只显示系统表。 |
pg_statio_user_tables |
与 pg_statio_all_tables 相同,但只显示用户表。 |
pg_statio_all_indexes |
当前数据库中的每个索引:该索引中的 磁盘块读取数和缓冲区命中数。 |
pg_statio_sys_indexes |
与 pg_statio_all_indexes 相同,但只显示系统表上的 索引。 |
pg_statio_user_indexes |
与 pg_statio_all_indexes 相同,但只显示用户表上的 索引。 |
pg_statio_all_sequences |
当前数据库中的每个序列对象:该序列中的 磁盘块读取数和缓冲区命中数。 |
pg_statio_sys_sequences |
与 pg_statio_all_sequences 相同,但只显示系统 序列。(目前没有定义任何系统序列, 因此该视图总是空的。) |
pg_statio_user_sequences |
与 pg_statio_all_sequences 相同,但只显示用户 序列。 |
每个索引的统计信息对于判断哪些索引正在被使用 以及它们有多有效尤其有用。
pg_statio_ 视图主要用来判断 缓冲缓存的有效性。当实际磁盘 读取数远小于缓冲区命中数时,缓存 正在不调用内核的情况下满足大多数 读请求。
通过编写使用与这些标准视图相同的底层 统计访问函数的查询,可以建立查看统计 信息的其他方式。每个数据库的访问 函数接受一个数据库 OID 来 标识要报告的数据库。每表和每 索引的函数接受一个表或索引 OID(注意,用这些函数只能看到 当前数据库中的表和 索引)。每个后端的访问 函数接受一个后端 ID 号,其范围从一到 当前活动 后端的数量。
表 10.2. 统计访问函数
| 函数 | 返回类型 | 描述 |
|---|---|---|
pg_stat_get_db_numbackends(oid) |
integer |
数据库中的活动后端数 |
pg_stat_get_db_xact_commit(oid) |
bigint |
数据库中已提交的事务数 |
pg_stat_get_db_xact_rollback(oid) |
bigint |
数据库中已回滚的事务数 |
pg_stat_get_db_blocks_fetched(oid) |
bigint |
数据库的磁盘块读取请求数 |
pg_stat_get_db_blocks_hit(oid) |
bigint |
数据库的在缓存中找到的磁盘块请求数 |
pg_stat_get_numscans(oid) |
bigint |
参数为表时是完成的顺序扫描数,参数为索引时是完成的索引扫描数 |
pg_stat_get_tuples_returned(oid) |
bigint |
参数为表时顺序扫描读取的元组数, 或参数为索引时读取的索引元组数 |
pg_stat_get_tuples_fetched(oid) |
bigint |
参数为表时顺序扫描取出的有效(未过期) 表元组数,或参数为索引时用该 索引的索引扫描取出的元组数 |
pg_stat_get_tuples_inserted(oid) |
bigint |
插入表的元组数 |
pg_stat_get_tuples_updated(oid) |
bigint |
表中更新的元组数 |
pg_stat_get_tuples_deleted(oid) |
bigint |
从表中删除的元组数 |
pg_stat_get_blocks_fetched(oid) |
bigint |
表或索引的磁盘块读取请求数 |
pg_stat_get_blocks_hit(oid) |
bigint |
表或索引的在缓存中找到的磁盘块请求数 |
pg_stat_get_backend_idset() |
set of integer |
当前活动后端 ID 的集合(从 1 到 N,N 为 活动 后端数)。用法示例见下文。 |
pg_stat_get_backend_pid(integer) |
integer |
后端进程的 PID |
pg_stat_get_backend_dbid(integer) |
oid |
后端进程的数据库 ID |
pg_stat_get_backend_userid(integer) |
oid |
后端进程的用户 ID |
pg_stat_get_backend_activity(integer) |
text |
后端进程的当前查询(调用者不是超级用户时为 NULL) |
注意:blocks_fetched 减去 blocks_hit 得到对该表、索引或 数据库发出的内核 read() 调用 数;但由于内核级缓冲,实际 物理读取数通常 更低。
函数 pg_stat_get_backend_idset 提供 一种为每个活动后端生成一行的便捷方法。例如, 要显示所有后端的 PID 和当前查询:
SELECT pg_stat_get_backend_pid(S.backendid) AS procpid,
pg_stat_get_backend_activity(S.backendid) AS current_query
FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS S;
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。