pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
PostgreSQL的统计收集器是一个支持收集和报告服务器活动信息的子系统。目前,收集器可以按磁盘块和单行两种方式统计对表和索引的访问。它还支持确定其他服务器进程当前正在执行的确切命令。
由于收集统计信息会增加查询执行的开销,因此可以配置系统是否收集信息。这由通常在postgresql.conf中设置的配置参数控制(有关设置配置参数的详细信息,请参阅第 16.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,默认配置下收集的统计信息很少。启用这些配置变量中的一个或多个,都会显著增加统计收集器产生的有用数据量,但代价是额外的运行时开销。
有若干预定义视图可用来显示统计收集的 结果,见 表 23.1。另外,也可以 用底层的统计函数构建自定义视图。
用统计信息监控当前活动时,重要的一点是 要认识到这些信息不会即时更新。 每个单独的服务器进程在等待下一条客户端命令 之前传输新的访问计数;因此仍在进行中的查询 不会影响显示的总量。此外,收集器本身 每最多 pgstat_stat_interval 毫秒(默认 500)才发出一次新的总量。因此显示的总量落后于 实际活动。
另一个要点是,当服务器进程被要求显示 这些统计信息中的任何一种时,它会先取回 收集器进程发出的最新总量,然后在当前 事务结束之前继续使用这一快照用于所有 统计视图和函数。 因此,只要继续当前事务,统计信息看起来就 不会变化。这是一个特性而不是缺陷,因为它 允许你对统计信息执行多个 查询并关联结果,而不必担心数字在 你手下变化。但如果想让每个查询都看到 新结果,请务必在任何事务 块之外执行查询。
表 23.1. 标准统计视图
| 视图名 | 描述 |
|---|---|
pg_stat_activity |
每个服务器进程一行,显示进程ID、数据库、用户、当前查询,以及当前查询开始执行的时间。报告当前查询数据的各列只有在参数stats_command_string被打开时才可用。此外,除非查看该视图的用户是超级用户或与被报告进程的属主是同一用户,这些列读取为空值。(注意,由于收集器的报告延迟,当前查询只对长时间运行的查询是最新的。) |
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_视图主要用于判断缓冲区缓存的有效性。 如果实际磁盘读取次数远少于缓冲区命中次数,缓存就能满足大多数读取请求,而无需调用内核。 不过,这些统计信息并不能反映全部情况:由于PostgreSQL处理磁盘 I/O 的方式, 不在PostgreSQL缓冲区缓存中的数据仍可能驻留在内核的 I/O 缓存中, 因而仍可在不执行物理读取的情况下取得。对于希望更详细地了解PostgreSQL I/O 行为的用户, 建议将PostgreSQL统计收集器与能够深入查看内核 I/O 处理情况的操作系统工具结合使用。
也可以通过编写查询来建立查看统计信息的其他方式,这些查询使用与标准视图相同的底层统计访问函数。这些函数列于表 23.2中。每数据库访问函数以数据库 OID 为参数来标识要报告的数据库。每表和每索引函数以表或索引 OID 为参数。(注意,用这些函数只能看到当前数据库中的表和索引。)每后端进程访问函数以一个后端进程 ID 为参数,其范围从 1 到当前活动的后端进程数。
表 23.2. 统计访问函数
| 函数 | 返回类型 | 描述 |
|---|---|---|
|
integer |
数据库的活动后端进程数 |
|
bigint |
数据库中提交的事务 |
|
bigint |
数据库中回滚的事务 |
|
bigint |
数据库的磁盘块读取请求数 |
|
bigint |
数据库在缓存中找到的磁盘块读取请求数 |
|
bigint |
参数为表时是完成的顺序扫描数,参数为索引时是完成的索引扫描数 |
|
bigint |
参数为表时是顺序扫描读取的行数,参数为索引时是读取的索引行数 |
|
bigint |
参数为表时是顺序扫描取出的有效(未过期)表行数,参数为索引时是使用该索引的索引扫描取出的表行数 |
|
bigint |
插入表中的行数 |
|
bigint |
表中更新的行数 |
|
bigint |
从表中删除的行数 |
|
bigint |
表或索引的磁盘块读取请求数 |
|
bigint |
表或索引在缓存中找到的磁盘块请求数 |
|
set of integer |
当前活动的后端进程 ID 的集合(从 1 到活动的后端进程数)。用法示例见正文。 |
|
integer |
附属于当前会话的后端进程的进程 ID |
|
integer |
给定后端进程的进程 ID |
|
oid |
给定后端进程的数据库 ID |
|
oid |
给定后端进程的用户 ID |
|
text |
给定后端进程的活动命令(如果当前用户既不是超级用户也不是被查询会话的用户,或者stats_command_string未打开,则为空值) |
|
timestamp with time zone(带时区的时间戳) |
给定后端进程当前执行的查询的启动时间(如果当前用户既不是超级用户也不是被查询会话的用户,或者stats_command_string未打开,则为空值) |
|
boolean |
重置当前收集到的所有统计信息 |
pg_stat_get_db_blocks_fetched减去pg_stat_get_db_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 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。