27.2. 统计收集器

PostgreSQL的统计收集器是一个支持收集和汇报服务器活跃性信息的子系统。 目前,这个收集器可以给出对表和索引的访问计数, 包括磁盘块的数量和独立行的项。它还跟踪每个表中的行的总数, 每个表的过去的清理和分析时间。它也可以计算用户定义的函数的调用, 以及每个人的总花费的时间。

PostgreSQL还可以判断当前其它服务器进程正在执行的命令是什么。 这是一个收集过程中的独立设施。

27.2.1. 统计收集器配置

因为统计收集给查询处理增加了一些开销,所以该系统可以配置为启用或禁用统计收集。 这是由配置参数控制的,通常在postgresql.conf里设置 (参阅Chapter 18获取有关设置配置参数的细节)。

参数track_activities启动监测任何服务器进程执行的当前命令。

参数track_counts控制关于表和索引是否被统计。

参数track_functions实现了对用户定义的函数用法的追踪。

参数track_io_timing启动监控块读写次数。

通常这些参数在postgresql.conf中设置,因此它们作用于所有服务器进程, 但是我们也可以在独立的会话里用SET命令把它们打开或者关闭。 为避免普通用户把它们的活跃性隐藏不给管理员看, 只有超级用户允许用SET命令修改这些参数。

统计收集器通过临时文件将采集到的信息传递给其他的PostgreSQL进程。 这些文件存放在stats_temp_directory参数命名的目录中。 缺省是pg_stat_tmp。 为了提高性能,stats_temp_directory参数可以指向一个基于RAM的文件系统, 降低物理I/O需求。当服务器关闭时, 统计数据的永久复本存储在global子目录中, 所以统计数据可以在服务器重新启动时保留。

27.2.2. 查看收集到的统计信息

有一些预定义的视图可以用于显示统计收集的结果, 在Table 27-1里列出。 另外,我们可以使用底层的统计函数制作自定义的视图。 正如Section 27.2.3中讨论的。

在使用统计观察当前活跃性的时候,你必须意识到这些信息并不是实时更新的。 每个独立的服务器进程只是在准备进入空闲状态的时候才向收集器传送新的块和行访问计数; 因此正在处理的查询或者事务并不影响显示出来的总数。同样, 收集器本身也最多每PGSTAT_STAT_INTERVAL毫秒 (缺省500,除非在编译服务器的时候修改过) 发送一次新的报告。因此显示总是落后于实际活动。 但是由track_activities收集的当前查询信息总是实时更新的。

另外一个需要着重指出的是,在请求服务器进程显示任何这些统计信息的时候, 它首先抓取收集器进程发出的最新报告,然后就拿这些数据作为所有统计视图和函数的快照, 直到它当前的事务结束。因此统计信息在当前事务的持续期间内显示静态信息。类似的, 每个进程的当前查询信息在该查询首次出现在事务中的时候就被收集了, 并且在整个事务过程中都显示相同的信息。这是一个特性,而不是一个臭虫, 因为这样就允许你在统计上执行几个查询并且对结果进行相关性检查而又不用担心这些数字会悄悄的变化。 但是如果你想看每个查询的最新结果,那么就要记住在事务块外面处理这些查询。 另外,你可以调用pg_stat_clear_snapshot(), 这将丢弃目前事务的统计数据快照(如有)。 下次使用统计信息将导致获取一个新的快照。

在视图pg_stat_xact_all_tablespg_stat_xact_sys_tablespg_stat_xact_user_tablespg_stat_xact_user_functions上事务也可以看到自己的统计(未传送到收集器)。 这些数字不能作为上面所说的;相反他们在整个事务中不断更新。

Table 27-1. 标准统计视图

视图名称 描述
pg_stat_activity 每个服务器进程一行,显示进程当前活动相关的信息,比如状态和当前查询。 参阅pg_stat_activity获取更多详情。
pg_stat_bgwriter 只有一行,显示关于后端写进程活动的统计信息。参阅pg_stat_bgwriter 获取更多详细信息。
pg_stat_database 每个数据库一行,显示数据库广泛的统计。参阅pg_stat_database获取更多详情。
pg_stat_all_tables 当前数据库每个表一行,显示关于访问特定表的统计。参阅pg_stat_all_tables 获取更多详细信息。
pg_stat_sys_tables pg_stat_all_tables一样,除了只显示系统表之外。
pg_stat_user_tables pg_stat_all_tables一样,除了只显示用户表。
pg_stat_xact_all_tables 类似pg_stat_all_tables, 但是到目前为止当前事务中计算采取的行动 (这包含在pg_stat_all_tables中以及相关视图中。) 活的列数以及死行和清理以及分析操作不在此视图中出现。
pg_stat_xact_sys_tables pg_stat_xact_all_tables相同,除了只显示系统表。
pg_stat_xact_user_tables pg_stat_xact_all_tables相同,除了只显示用户表。
pg_stat_all_indexes 当前数据库中的每个索引的每一行,显示关于访问特定索引的统计。 参见pg_stat_all_indexes获取更多详情。
pg_stat_sys_indexes pg_stat_all_indexes一样,但只显示系统表上的索引。
pg_stat_user_indexes pg_stat_all_indexes一样,但只显示用户表上的索引。
pg_statio_all_tables 当前数据库每个表一行,显示特定表关于I/O的统计, 参阅pg_statio_all_tables 获取更多细节。
pg_statio_sys_tables pg_statio_all_tables一样,但只显示系统表
pg_statio_user_tables pg_statio_all_tables一样,但只显示用户表。
pg_statio_all_indexes 当前数据库每个索引一行,显示特定索引关于I/O的统计。 参阅pg_statio_all_indexes获取更多细节。
pg_statio_sys_indexes pg_statio_all_indexes一样的,但是只显示系统表上的索引。
pg_statio_user_indexes pg_statio_all_indexes一样,但只显示用户表上的索引。
pg_statio_all_sequences 当前数据库每个序列一行,显示特定序列关于I/O的统计。参阅 pg_statio_all_sequences获取更多细节。
pg_statio_sys_sequences pg_statio_all_sequences一样, 但只显示系统序列。因为目前没有定义系统序列,所以这个视图总是空的。
pg_statio_user_sequences pg_statio_all_sequences一样,但只显示用户序列。
pg_stat_user_functions 每一个跟踪函数一行,显示关于执行这个函数的统计。 参阅pg_stat_user_functions 获取更多详情。
pg_stat_xact_user_functions 类似于pg_stat_user_functions,但是在当前事务中只调用计数 (这不包含在pg_stat_user_functions中)。
pg_stat_replication 每WAL发送进程一行,显示关于复制到发送端的链接备用服务器的统计信息。 参阅pg_stat_replication获取更多细节。
pg_stat_database_conflicts 每个数据库一行,显示关于备用服务器恢复冲突取消查询的统计信息。 参阅pg_stat_database_conflicts获取更多信息。

针对每个索引的统计有利于判断哪个索引得到使用以及它们的效果。

pg_statio_视图有利于决定缓冲区高速缓存的有效性。 当实际的磁盘数读取比缓冲区的数目小得多的时候, 然后缓存满足大多数读请求而没有调用内核调用。 然而,这些统计数据不提供整个过程:由于PostgreSQL 处理磁盘I/O的方式,不在PostgreSQL缓冲区缓存中的数据可能仍然位于 内核I/O缓存中,因此可能仍然被取出而不需要物理读。 对获得更多PostgreSQL的I/O行为的详细信息感兴趣的用户 建议使用与操作系统工具结合的PostgreSQL统计收集, 允许洞察I/O的内核处理。

Table 27-2. pg_stat_activity视图

类型 描述
datid oid 连接后端的数据库OID
datname name 连接后端的数据库名称
pid integer 后端进程ID
usesysid oid 登陆后端的用户OID
usename name 登陆到该后端的用户名
application_name text 连接到后端的应用名
client_addr inet 连接到后端的客户端的IP地址。 如果此字段是null, 它表明通过服务器机器上UNIX套接字连接客户端或者这是内部进程如autovacuum
client_hostname text 连接客户端的主机名,通过client_addr的反向DNS查找报告。 这个字段将只是非空的IP连接,并且仅仅当启动log_hostname的时候。
client_port integer 客户端用于与后端通讯的TCP端口号,或者如果使用Unix套接字,则为-1
backend_start timestamp with time zone 该过程开始的时间,比如当客户端连接服务器时。
xact_start timestamp with time zone 启动当前事务的时间,如果没有事务是活的,则为null。如果当前查询是 首个事务,则这列等同于query_start列。
query_start timestamp with time zone 开始当前活跃查询的时间, 或者如果state是非活跃的, 当开始最后查询时。
state_change timestamp with time zone 上次状态改变的时间
waiting boolean 如果后端当前正等待锁则为真
state text 该后端当前总体状态。可能值是: 活跃的:后端正在执行一个查询。 空闲的:后端正在等待一个新的客户端命令。 空闲事务:后端在事务中,但是目前无法执行查询。 空闲事务(被终止):这个情况类似于空闲事务,除了事务导致错误的一个语句之一。 快速路径函数调用:后端正在执行一个快速路径函数。 禁用:如果后端禁用track_activities,则报告这个状态。
query text 该后端的最新查询文本。如果状态活跃的, 此字段显示当前正在执行的查询。在所有其他情况中,这表明执行过去的查询。

pg_stat_activity每个服务器进程有一行,显示进程当前活动的相关信息。

Note: waitingstate列是独立的。 如果一个后端处于活跃状态,它可能会或可能不会waiting。 如果这种情况是活跃的并且waiting是真, 它意味着正在执行一个查询,但在该系统中的某个地方被锁阻塞。

Table 27-3. pg_stat_bgwriter视图

类型 描述
checkpoints_timed bigint 执行的定期检查点数
checkpoints_req bigint 执行的需求检查点数
checkpoint_write_time double precision 花费在检查点处理部分的时间总量,其中文件被写入到磁盘,以毫秒为单位。
checkpoint_sync_time double precision 花费在检查点处理部分的时间总量,其中文件被同步到磁盘,以毫秒为单位。
buffers_checkpoint bigint 检查点写缓冲区数量
buffers_clean bigint 后端写进程写缓冲区数量
maxwritten_clean bigint 后端写进程停止清理扫描时间数,因为它写了太多缓冲区
buffers_backend bigint 通过后端直接写缓冲区数
buffers_backend_fsync bigint 后端不得不执行自己的fsync调用的时间数 (通常后端写进程处理这些即使后端确实自己写)
buffers_alloc bigint 分配的缓冲区数量
stats_reset timestamp with time zone 这些统计被重置的时间

pg_stat_bgwriter视图总是有独立行,包含集群的全局数据。

Table 27-4. pg_stat_database视图

类型 描述
datid oid 数据库的OID
datname name 这个数据库的名字
numbackends integer 当前连接到该数据库的后端数。 这是在返回一个反映目前状态值的视图中唯一的列;自 上次重置所有其他列返回累积值。
xact_commit bigint 此数据库中已经提交的事务数
xact_rollback bigint 此数据库中已经回滚的事务数
blks_read bigint 在这个数据库中读取的磁盘块的数量
blks_hit bigint 高速缓存中已经发现的磁盘块的次数, 这样读取是不必要的(这只包括PostgreSQL缓冲区高速缓存,没有操作系统的文件系统缓存。
tup_returned bigint 通过数据库查询返回的行数
tup_fetched bigint 通过数据库查询抓取的行数
tup_inserted bigint 通过数据库查询插入的行数
tup_updated bigint 通过数据库查询更新的行数
tup_deleted bigint 通过数据库查询删除的行数
conflicts bigint 由于数据库恢复冲突取消的查询数量。(只在备用服务器发生的冲突);参阅 pg_stat_database_conflicts获取更多信息。
temp_files bigint 通过数据库查询创建的临时文件数量。计算所有临时文件, 不论为什么创建临时文件(比如排序或者哈希), 而且不管log_temp_files设置。
temp_bytes bigint 通过数据库查询写入临时文件的数据总量。计算所有临时文件, 不论为什么创建临时文件, 而且不管log_temp_files设置
deadlocks bigint 在该数据库中检索的死锁数
blk_read_time double precision 通过数据库后端读取数据文件块花费的时间,以毫秒计算。
blk_write_time double precision 通过数据库后端写入数据文件块花费的时间,以毫秒计算。
stats_reset timestamp with time zone 这些统计最后被重置的时间

pg_stat_database视图将包含集群中每个数据库的每一行, 显示数据库统计。

Table 27-5. pg_stat_all_tables视图

类型 描述
relid oid 表的OID
schemaname name 此表的模式名
relname name 表名
seq_scan bigint 此表发起的顺序扫描数
seq_tup_read bigint 顺序扫描抓取的活跃行数
idx_scan bigint 此表发起的索引扫描数
idx_tup_fetch bigint 索引扫描抓取的活跃行数
n_tup_ins bigint 插入行数
n_tup_upd bigint 更新行数
n_tup_del bigint 删除行数
n_tup_hot_upd bigint HOT更新行数(比如没有更新所需的单独索引)
n_live_tup bigint 估计活跃行数
n_dead_tup bigint 估计死行数
last_vacuum timestamp with time zone 最后一次此表是手动清理的(不计算VACUUM FULL
last_autovacuum timestamp with time zone 上次被autovacuum守护进程清理的表
last_analyze timestamp with time zone 上次手动分析这个表
last_autoanalyze timestamp with time zone 上次被autovacuum守护进程分析的表
vacuum_count bigint 这个表被手动清理的次数(不计算VACUUM FULL
autovacuum_count bigint 这个表被autovacuum清理的次数
analyze_count bigint 这个表被手动分析的次数
autoanalyze_count bigint 这个表被autovacuum守护进程分析的次数

pg_stat_all_tables视图将包含 当前数据库中每个表的一行(包括TOAST表),显示访问特定表的统计信息。 pg_stat_user_tablespg_stat_sys_tables视图 包含相同的信息,但是过滤只分别显示用户和系统表。

Table 27-6. pg_stat_all_indexes视图

类型 描述
relid oid 这个索引的表的OID
indexrelid oid 索引的OID
schemaname name 索引中模式名
relname name 索引的表名
indexrelname name 索引名
idx_scan bigint 索引上开始的索引扫描数
idx_tup_read bigint 通过索引上扫描返回的索引项数
idx_tup_fetch bigint 通过使用索引的简单索引扫描抓取的活表行数

pg_stat_all_indexes视图将包含 当前数据库中的每个索引行,显示访问特定索引的统计。 pg_stat_user_indexespg_stat_sys_indexes视图包含相同的信息, 但是过滤只是分别显示用户和系统索引。

索引可以通过简单的索引扫描或"位图"索引扫描进行使用。位图扫描中 几个索引的输出可以通过AND或者OR规则进行组合, 因此当使用位图扫描的时候,很难将独立堆行抓取与特定索引进行组合, 因此,一个位图扫描增加pg_stat_all_indexes.idx_tup_read 使用索引计数,并且增加pg_stat_all_tables.idx_tup_fetch 表计数,但不影响pg_stat_all_indexes.idx_tup_fetch

Note: idx_tup_readidx_tup_fetch计算不同甚至没有任何可使用的位图扫描。 因为idx_tup_read计算从索引检索的索引项而idx_tup_fetch 计算从表抓取的活的行。如果任何死的或尚未提交的行使用索引进行抓取, 或通过唯一索引扫描避免任何堆抓取,则后者较小。

Table 27-7. pg_statio_all_tables视图

类型 描述
relid oid 表OID
schemaname name 该表模式名
relname name 表名
heap_blks_read bigint 从该表中读取的磁盘块数
heap_blks_hit bigint 此表缓存命中数
idx_blks_read bigint 从表中所有索引读取的磁盘块数
idx_blks_hit bigint 表中所有索引命中缓存数
toast_blks_read bigint 此表的TOAST表读取的磁盘块数(如果存在)
toast_blks_hit bigint 此表的TOAST表命中缓冲区数(如果存在)
tidx_blks_read bigint 此表的TOAST表索引读取的磁盘块数(如果存在)
tidx_blks_hit bigint 此表的TOAST表索引命中缓冲区数(如果存在)

pg_statio_all_tables视图将包含 当前数据库中每个表的一行(包括TOAST表), 显示出特定表I/O的统计。pg_statio_user_tablespg_statio_sys_tables视图包含相同的信息, 但是过滤分别只显示用户和系统表。

Table 27-8. pg_statio_all_indexes视图

类型 描述
relid oid 索引的表的OID
indexrelid oid 该索引的OID
schemaname name 该索引的模式名
relname name 该索引的表名
indexrelname name 索引名称
idx_blks_read bigint 从索引中读取的磁盘块数
idx_blks_hit bigint 索引命中缓存数

pg_statio_all_indexes视图将包含当前数据库中的每个索引行, 显示特定索引的I/O的统计。pg_statio_user_indexespg_statio_sys_indexes视图包含相同的信息, 但是过滤分别只显示用户和系统索引。

Table 27-9. pg_statio_all_sequences视图

类型 描述
relid oid 序列OID
schemaname name 序列中模式名
relname name 序列名
blks_read bigint 从序列中读取的磁盘块数
blks_hit bigint 序列中缓存命中数

pg_statio_all_sequences视图包含当前数据库中每个序列的每一行, 显示特定序列关于I/O的统计。

Table 27-10. pg_stat_user_functions视图

类型 描述
funcid oid 函数OID
schemaname name 此函数中的模式名
funcname name 函数名
calls bigint 被调用的函数次数
total_time double precision 在这个函数以及调用的其他函数的总时间,以毫秒为单位。
self_time double precision 在这个函数本身上用的总时间,不包含调用其他函数的,以毫秒为单位

pg_stat_user_functions视图包含每个跟踪函数的行,显示关于函数执行的统计。 track_functions参数控制真正跟踪的函数。

Table 27-11. pg_stat_replication视图

类型 描述
pid integer WAL发送进程的ID
usesysid oid 登陆到这个WAL发送进程的用户OID
usename name 登陆到WAL发送进程的用户名
application_name text 连接到这个WAL发送端的应用名
client_addr inet 客户端连接到这个WAL发送端的IP地址,如果这个字段为null,它表明通过 服务器上Unix套接字连接客户端。
client_hostname text 连接客户端的主机名,通过client_addr的反向DNS查找报告。 并且当启用log_hostname时,这个字段对于IP连接是非空的。
client_port integer 客户端正在使用与WAL发送端连接的TCP端口号,或者如果使用Unix套接字则为-1
backend_start timestamp with time zone 这个进程开始时的时间,比如当客户端连接到这个WAL发送端时。
state text 当前WAL发送端状态
sent_location text 在这次连接上发送的上次事务日志位置
write_location text 通过备用服务器写入到磁盘的上次事务日志位置。
flush_location text 通过备用服务器刷新到磁盘的上次事务日志位置。
replay_location text 备用服务器上重播到数据库的上次事务日志位置。
sync_priority integer 这个备用服务器被选为同步备用的优先级。
sync_state text 该备用服务器的同步状态

pg_stat_replication视图包含每个WAL发送进程的每一行, 显示发送端连接备用服务器有关复制的统计。列出只直接连接的备用; 没有可用的下游备用服务器的信息。

Table 27-12. pg_stat_database_conflicts视图

类型 描述
datid oid 数据库的OID
datname name 数据库名称
confl_tablespace bigint 由于删除的表空间,已经取消的数据库中的查询数量
confl_lock bigint 由于锁超时,已经取消的数据库中的查询数
confl_snapshot bigint 由于旧快照,已经取消的数据库查询数
confl_bufferpin bigint 由于保留区而取消的数据库查询数
confl_deadlock bigint 由于死锁已经被取消的数据库中的查询数

pg_stat_database_conflicts视图将包含 每个数据库的一行,显示由于备用服务器恢复发生的冲突而取消查询的数据库范围统计信息。 这种视图将只包含备用服务器的信息,因为在主服务器上不会发生冲突。

27.2.3. 统计函数

查看统计的其他方式可以通过写查询设置,它使用相同的底层统计访问功能用于 上面显示的标准视图。函数名称的详细信息,请参考标准的视图定义。(例如, 在psql中你可以发出\d+ pg_stat_activity。) 每个数据库统计的访问函数以数据库OID作为参数识别报告给数据库。 每个表和索引函数看成表或索引的OID。每个函数统计采取一个函数OID。 请注意,只有当前数据库中的表,索引,和函数可以看出这些功能。

统计收集相关的附加函数列在Table 27-13中。

Table 27-13. 附加统计函数

函数 返回类型 描述
pg_backend_pid() integer 服务器进程处理当前会话的进程ID
pg_stat_get_activity`(integer`) setof record 如果声明为NULL,则返回特定PID后端信息记录,或者系统中每个活动后端的记录。 返回的字段是pg_stat_activity视图中的子集。
pg_stat_clear_snapshot() void 丢弃当前数据库快照
pg_stat_reset() void 所有当前数据库统计计数器重置为零(需要超级用户权限)
`pg_stat_reset_shared(text)` void 重置一些集群范围统计计数为零,依赖于参数(需要超级用户权限)。 所有显示在pg_stat_bgwriter视图中的计数器调用pg_stat_reset_shared('bgwriter')将归零。
`pg_stat_reset_single_table_counters(oid)` void 为当前数据库中单一表或者索引重置统计为零(需要超级用户权限)
`pg_stat_reset_single_function_counters(oid)` void 当前数据库中单一功能重置统计为零(需要超级用户权限)

pg_stat_get_activitypg_stat_activity视图的基本功能返回 包含每个后端进程的所有可用信息的记录集。有时获取这些信息的子集更方便。 在这种情况下,可以使用每个后端统计访问函数的旧设置。这些都显示在 Table 27-14中。这些访问函数使用后端ID号, 其范围从一到当前活动后端数。 函数pg_stat_get_backend_idset提供便利方式产生调用这些函数的每个活动后端的每一行。 比如,显示PID以及所有后端的当前查询:

SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
       pg_stat_get_backend_activity(s.backendid) AS query
    FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;

Table 27-14. 每个后端统计函数

函数 返回类型 描述
pg_stat_get_backend_idset() setof integer 设置当前活动的后端ID号(从1到活动后端数)
pg_stat_get_backend_activity(integer) text 后端最近查询文本
pg_stat_get_backend_activity_start(integer) timestamp with time zone 最近查询开始时间
pg_stat_get_backend_client_addr(integer) inet 连接后端的客户端IP地址
pg_stat_get_backend_client_port(integer) integer 客户端用于通讯的TCP端口号
pg_stat_get_backend_dbid(integer) oid 连接后端的数据库OID
pg_stat_get_backend_pid(integer) integer 后端进程ID
pg_stat_get_backend_start(integer) timestamp with time zone 进程开始时间
pg_stat_get_backend_userid(integer) oid 登陆到后端的用户OID
pg_stat_get_backend_waiting(integer) boolean 如果后端正等待锁则为真
pg_stat_get_backend_xact_start(integer) timestamp with time zone 当前事务的开始时间