PostgreSQL的统计收集器是一个支持收集和报告服务器活动信息的子系统。 目前,对表和索引的访问以磁盘块和单个行的术语进行计数。每个表中的总行数, 以及每个表的清理和分析操作的信息也被计数。如果启用,对用户定义函数的调用 和每个函数中花费的总时间也会被计数。
PostgreSQL也支持报告关于系统当前正在发生的情况的动态信息, 例如其他服务器进程当前正在执行的确切命令,以及系统中存在哪些其他连接。此功能独立于收集器进程。
由于收集统计信息会增加查询执行的开销,因此可以配置系统是否收集信息。这由通常在postgresql.conf中设置的配置参数控制(有关设置配置参数的详细信息,请参阅Chapter 19)。
参数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 需求。 当服务器正常关闭时,统计信息数据的永久副本会存储在pg_stat子目录中,以便在服务器重启后保留这些统计信息。 当服务器启动时执行恢复时(例如立即关闭后、服务器崩溃后以及进行时间点恢复时),所有统计计数器都会被重置。
有几个预定义视图列在Table 28.1中,可用于显示系统的当前状态。另有几个视图列在Table 28.2中,可用于显示统计信息收集的结果。或者,也可以像Section 28.2.3中所述那样,使用底层的统计函数构建自定义视图。
当使用统计信息来监视收集到的数据时,重要的是要意识到信息不会立即更新。每个单独的服务器进程会在转为空闲之前把新的统计计数发送给收集器,因此仍在进行中的查询或事务不会影响显示的总计。并且,收集器本身最多每隔PGSTAT_STAT_INTERVAL毫秒才会发出一份新报告一次(除非在构建服务器时做过修改,否则为 500 毫秒)。因此,显示的信息会滞后于实际活动。然而,由track_activities收集的当前查询信息始终是最新的。
另一个重要点是,当要求服务器进程显示这些统计信息中的任何一种时,它会先取回收集器进程最近发出的报告,然后在当前事务结束之前,对所有统计视图和函数一直使用这一快照。因此,只要你继续当前事务,统计信息就会显示静态信息。类似地,在事务中第一次请求任意当前会话的查询信息时,就会收集所有会话当前查询的信息,并且在整个事务期间显示的都是同一份信息。这是一个特性,而不是一个错误,因为它允许你对统计信息执行多个查询并对结果做关联,而不必担心数字在你眼前变化。但如果希望每个查询都看到新的结果,请确保在任何事务块之外执行这些查询。或者,也可以调用pg_stat_clear_snapshot(),它会丢弃当前事务的统计快照(如果有)。下一次使用统计信息时,就会获取一个新的快照。
事务还可以在视图pg_stat_xact_all_tables、 pg_stat_xact_sys_tables、 pg_stat_xact_user_tables和 pg_stat_xact_user_functions中看到自己的统计信息 (这些统计信息尚未传送给收集器)。这些数字不像上面所述那样起作用; 相反,它们在事务期间持续更新。
Table 28.1. 动态统计视图
| 视图名称 | 描述 |
|---|---|
pg_stat_activity |
每个服务器进程一行,显示与该进程当前活动有关的信息,例如状态和当前查询。详见pg_stat_activity。 |
pg_stat_replication |
每个 WAL 发送进程一行,显示向其所连接的备库进行复制的统计信息。详见pg_stat_replication。 |
pg_stat_wal_receiver |
只有一行,显示 WAL 接收进程从其所连接服务器接收数据的统计信息。详见pg_stat_wal_receiver。 |
pg_stat_subscription |
每个订阅至少一行,显示订阅工作进程的信息。详见pg_stat_subscription。 |
pg_stat_ssl |
每个连接(普通连接和复制连接)一行,显示此连接所使用 SSL 的信息。详见pg_stat_ssl。 |
pg_stat_progress_vacuum |
每个正在运行VACUUM的后端(包括自动清理工作进程)一行,显示当前进度。请参阅Section 28.4.1。 |
Table 28.2. 已收集统计信息的视图
| 视图名称 | 描述 |
|---|---|
pg_stat_archiver |
只有一行,显示 WAL 归档进程活动的统计信息。详见pg_stat_archiver。 |
pg_stat_bgwriter |
只有一行,显示后台写入进程活动的统计信息。详见pg_stat_bgwriter。 |
pg_stat_database |
每个数据库一行,显示整个数据库的统计信息。详见pg_stat_database。 |
pg_stat_database_conflicts |
每个数据库一行,显示备库上因与恢复冲突而取消查询的数据库范围统计信息。详见pg_stat_database_conflicts。 |
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_statio_视图主要用于判断缓冲区缓存的有效性。 如果实际磁盘读取次数远少于缓冲区命中次数,缓存就能满足大多数读取请求,而无需调用内核。 不过,这些统计信息并不能反映全部情况:由于PostgreSQL处理磁盘 I/O 的方式, 不在PostgreSQL缓冲区缓存中的数据仍可能驻留在内核的 I/O 缓存中, 因而仍可在不执行物理读取的情况下取得。对于希望更详细地了解PostgreSQL I/O 行为的用户, 建议将PostgreSQL统计收集器与能够深入查看内核 I/O 处理情况的操作系统工具结合使用。
Table 28.3. pg_stat_activity 视图
| 列 | 类型 | 描述 |
|---|---|---|
datid |
oid |
这个后端连接到的数据库的OID |
datname |
name |
这个后端连接到的数据库的名称 |
pid |
integer |
这个后端的进程 ID |
usesysid |
oid |
登录到这个后端的用户的 OID |
usename |
name |
登录到此后端的用户名称 |
application_name |
text |
连接到此后端的应用名称 |
client_addr |
inet |
连接到这个后端的客户端的 IP 地址。如果这个字段为空,它表示客户端通过服务器机器上的一个 Unix 套接字连接或者这是一个内部进程,如自动清理。 |
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 |
这个进程的当前事务被启动的时间,如果没有活动事务则为空。 如果当前查询是它的第一个事务,这一列等于query_start列。 |
query_start |
timestamp with time zone |
当前活动查询开始的时间;如果state不是active,则为上一个查询的开始时间 |
state_change |
timestamp with time zone |
state上一次发生改变的时间 |
wait_event_type |
text |
后端正在等待的事件类型(如果有),否则为 NULL。可能的值为:
|
wait_event |
text |
如果后端当前正在等待,则为等待事件名称,否则为 NULL。详见Table 28.4。 |
state |
text |
该后端当前的总体状态。可能的值为:
|
backend_xid |
xid |
这个后端的顶层事务 ID,如果存在。 |
backend_xmin |
xid |
当前后端的xmin范围。 |
query |
text |
这个后端最近查询的文本。如果state为active,这个字段显示当前正在执行的查询。 在所有其他状态下,它显示上一个被执行的查询。默认情况下,查询文本会被截断至1024个字节,这个值可以通过参数track_activity_query_size更改。 |
backend_type |
text |
当前后端的类型。可能的类型为autovacuum launcher、autovacuum worker、background worker、background writer、client backend、checkpointer、startup、walreceiver、walsender和walwriter。 |
pg_stat_activity视图每个服务器进程将有一行,显示与该进程当前活动相关的信息。
wait_event和state列彼此独立。如果某个后端处于active状态,它可能在等待(waiting)某个事件,也可能没有等待。如果状态为active且wait_event非空,就意味着某个查询正在执行,但在系统中的某处被阻塞了。
Table 28.4. wait_event 描述
| 等待事件类型 | 等待事件名称 | 描述 |
|---|---|---|
LWLock |
ShmemIndexLock |
等待在共享内存中找到或分配空间。 |
OidGenLock |
等待分配或指派 OID。 | |
XidGenLock |
等待分配或指派事务 ID。 | |
ProcArrayLock |
等待获取快照,或在事务结束时清除事务 ID。 | |
SInvalReadLock |
等待从共享失效队列中取出或移除消息。 | |
SInvalWriteLock |
等待向共享失效队列添加消息。 | |
WALBufMappingLock |
等待在WAL缓冲区中替换一个页面。 | |
WALWriteLock |
等待WAL缓冲区写入磁盘。 | |
ControlFileLock |
等待读取或更新控制文件,或创建新的 WAL 文件。 | |
CheckpointLock |
等待执行检查点。 | |
CLogControlLock |
等待读取或更新事务状态。 | |
SubtransControlLock |
等待读取或更新子事务信息。 | |
MultiXactGenLock |
等待读取或更新共享的multixact状态。 | |
MultiXactOffsetControlLock |
等待读取或更新多事务偏移映射。 | |
MultiXactMemberControlLock |
等待读取或更新多事务成员映射。 | |
RelCacheInitLock |
等待读取或写入关系缓存初始化文件。 | |
CheckpointerCommLock |
等待管理fsync请求。 | |
TwoPhaseStateLock |
等待读取或更新已准备事务的状态。 | |
TablespaceCreateLock |
等待创建或删除表空间。 | |
BtreeVacuumLock |
等待读取或更新B-树索引的清理相关信息。 | |
AddinShmemInitLock |
等待管理共享内存中的空间分配。 | |
AutovacuumLock |
自动清理工作进程或启动进程正在等待更新或读取自动清理工作进程的当前状态。 | |
AutovacuumScheduleLock |
等待确认已选定要清理的表仍然需要清理。 | |
SyncScanLock |
等待获取同步扫描所用的表扫描起始位置。 | |
RelationMappingLock |
等待更新用于存储目录到文件节点映射的关系映射文件。 | |
AsyncCtlLock |
等待读取或更新共享通知状态。 | |
AsyncQueueLock |
等待读取或更新通知消息。 | |
SerializableXactHashLock |
等待获取或存储可序列化事务的信息。 | |
SerializableFinishedListLock |
等待访问已完成的可串行化事务列表。 | |
SerializablePredicateLockListLock |
等待对可序列化事务所持有的锁列表执行操作。 | |
OldSerXidLock |
等待读取或记录相互冲突的可序列化事务。 | |
SyncRepLock |
等待读取或更新同步副本的信息。 | |
BackgroundWorkerLock |
等待读取或更新后台工作进程状态。 | |
DynamicSharedMemoryControlLock |
等待读取或更新动态共享内存状态。 | |
AutoFileLock |
等待更新postgresql.auto.conf文件。 |
|
ReplicationSlotAllocationLock |
等待分配或释放复制槽。 | |
ReplicationSlotControlLock |
等待读取或更新复制槽状态。 | |
CommitTsControlLock |
等待读取或更新事务提交时间戳。 | |
CommitTsLock |
等待读取或更新最近设置的事务时间戳值。 | |
ReplicationOriginLock |
等待设置、删除或使用复制源。 | |
MultiXactTruncationLock |
等待读取或截断multixact信息。 | |
OldSnapshotTimeMapLock |
等待读取或更新旧的快照控制信息。 | |
BackendRandomLock |
等待生成随机数。 | |
LogicalRepWorkerLock |
等待对逻辑复制工作进程的操作完成。 | |
CLogTruncationLock |
等待执行txid_status,或更新该函数可用的最早事务 ID。 |
|
WrapLimitsVacuumLock |
等待更新事务 ID和multixact消费的限制。 | |
NotifyQueueTailLock |
等待更新通知消息存储的限制。 | |
clog |
等待 clog(事务状态)缓冲区上的 I/O。 | |
commit_timestamp |
等待提交时间戳缓冲区上的 I/O。 | |
subtrans |
等待子事务缓冲区上的 I/O。 | |
multixact_offset |
等待多事务偏移缓冲区上的 I/O。 | |
multixact_member |
等待 multixact_member 缓冲区上的 I/O。 | |
async |
等待 async(通知)缓冲区上的 I/O。 | |
oldserxid |
等待 oldserxid 缓冲区上的 I/O。 | |
wal_insert |
等待将 WAL 插入内存缓冲区。 | |
buffer_content |
等待读取或写入内存中的数据页。 | |
buffer_io |
等待数据页上的 I/O。 | |
replication_origin |
等待读取或更新复制进度。 | |
replication_slot_io |
在复制槽上等待I/O。 | |
proc |
等待读取或更新快速路径锁信息。 | |
buffer_mapping |
等待将数据块与缓冲池中的缓冲区关联。 | |
lock_manager |
等待添加或检查后端的锁,或者等待加入或退出锁组(用于并行查询)。 | |
predicate_lock_manager |
等待添加或检查谓词锁信息。 | |
parallel_query_dsa |
等待并行查询的动态共享内存分配锁。 | |
tbm |
等待 TBM 共享迭代器锁。 | |
Lock |
relation |
等待获得一个关系的锁。 |
extend |
等待扩展一个关系。 | |
frozenid |
等待升级 pg_database.datfrozenxid 和 pg_database.datminmxid. |
|
page |
等待获取关系页上的锁。 | |
tuple |
等待获取元组上的锁。 | |
transactionid |
等待事务完成。 | |
virtualxid |
等待获取虚拟事务 ID 锁。 | |
speculative token |
等待获取推测的插入锁。 | |
object |
等待获取非关系数据库对象上的锁。 | |
userlock |
等待获取用户锁。 | |
advisory |
等待获得一个建议用户锁。 | |
BufferPin |
BufferPin |
等待获取缓冲区上的钉住。 |
Activity |
ArchiverMain |
在归档进程的主循环中等待。 |
AutoVacuumMain |
在自动清理启动过程的主循环中等待。 | |
BgWriterHibernate |
在后台写入器中等待,休眠状态。 | |
BgWriterMain |
在后台写入进程这一后台工作进程的主循环中等待。 | |
CheckpointerMain |
在检查点进程的主循环中等待。 | |
LogicalApplyMain |
在逻辑应用进程的主循环中等待。 | |
LogicalLauncherMain |
在逻辑启动进程的主循环中等待。 | |
PgStatMain |
在统计收集器进程的主循环中等待。 | |
RecoveryWalAll |
在恢复期间等待来自流的 WAL。 | |
RecoveryWalStream |
在恢复期间,若所有来源(本地、归档或流)都没有可用的 WAL 数据,则在重新尝试获取 WAL 数据前等待。 | |
SysLoggerMain |
在 syslogger 进程的主循环中等待。 | |
WalReceiverMain |
在WAL 接收进程的主循环中等待。 | |
WalSenderMain |
在 WAL 发送进程的主循环中等待。 | |
WalWriterMain |
在WAL写入进程的主循环中等待。 | |
Client |
ClientRead |
等待从客户端读取数据。 |
ClientWrite |
等待写入数据到客户端。 | |
LibPQWalReceiverConnect |
在WAL 接收进程等待与远程服务器建立连接。 | |
LibPQWalReceiverReceive |
在WAL 接收进程中等待从远程服务器接收数据。 | |
SSLOpenServer |
在尝试连接时等待SSL。 | |
WalReceiverWaitStart |
等待启动进程为流复制发送初始数据。 | |
WalSenderWaitForWAL |
在 WAL 发送进程中等待 WAL 被刷新。 | |
WalSenderWriteData |
在 WAL 发送进程中处理 WAL 接收进程的回复时,等待任何活动。 | |
Extension |
Extension |
在扩展中等待。 |
IPC |
BgWorkerShutdown |
等待后台工作进程关闭。 |
BgWorkerStartup |
等待后台工作进程启动。 | |
BtreePage |
正等待继续并行B-树扫描所需的页号变得可用。 | |
ExecuteGather |
在执行Gather节点时等待子进程的活动。 |
|
LogicalSyncData |
等待逻辑复制远程服务器为初始表同步发送数据。 | |
LogicalSyncStateChange |
等待逻辑复制远程服务器改变状态。 | |
MessageQueueInternal |
等待其他进程附加到共享消息队列。 | |
MessageQueuePutMessage |
等待将协议消息写入共享消息队列。 | |
MessageQueueReceive |
等待从共享消息队列接收字节。 | |
MessageQueueSend |
等待将字节发送到共享消息队列。 | |
ParallelBitmapScan |
等待并行位图扫描被初始化。 | |
ParallelFinish |
等待并行工作人员完成计算。 | |
ProcArrayGroupUpdate |
等待组领导者在事务结束时清除事务 ID。 | |
ReplicationOriginDrop |
等待复制源变为非活动状态,以便将其删除。 | |
ReplicationSlotDrop |
等待复制槽变为非活动状态,以便将其删除。 | |
SafeSnapshot |
等待READ ONLY DEFERRABLE事务的快照。 |
|
SyncRep |
在同步复制期间等待远程服务器的确认。 | |
Timeout |
BaseBackupThrottle |
当有限流活动时在基础备份期间等待。 |
PgSleep |
调用pg_sleep的进程正在等待。 |
|
RecoveryApplyDelay |
在恢复期间,由于应用 WAL 被延迟而等待。 | |
IO |
BufFileRead |
等待从缓冲文件中读取。 |
BufFileWrite |
等待对缓冲文件的写入。 | |
ControlFileRead |
等待读取控制文件。 | |
ControlFileSync |
等待控制文件写入持久存储。 | |
ControlFileSyncUpdate |
等待控制文件的更新写入持久存储。 | |
ControlFileWrite |
等待写入控制文件。 | |
ControlFileWriteUpdate |
等待写入以更新控制文件。 | |
CopyFileRead |
在文件复制操作期间等待读取。 | |
CopyFileWrite |
在文件拷贝操作期间等待写入。 | |
DataFileExtend |
等待关系数据文件被扩展。 | |
DataFileFlush |
等待关系数据文件达到持久存储。 | |
DataFileImmediateSync |
等待关系数据文件到持久存储的立即同步。 | |
DataFilePrefetch |
等待关系数据文件的异步预取。 | |
DataFileRead |
等待对关系数据文件的读取。 | |
DataFileSync |
等待对关系数据文件的更改达到持久存储。 | |
DataFileTruncate |
等待关系数据文件被截断。 | |
DataFileWrite |
等待对关系数据文件的写入。 | |
DSMFillZeroWrite |
等待将零字节写入动态共享内存的后备文件。 | |
LockFileAddToDataDirRead |
在向数据目录锁文件中添加一行时等待读取。 | |
LockFileAddToDataDirSync |
等待数据到达持久存储,同时向数据目录锁文件添加一行。 | |
LockFileAddToDataDirWrite |
在向数据目录锁文件中添加一行时等待写操作。 | |
LockFileCreateRead |
创建数据目录锁文件时等待读取。 | |
LockFileCreateSync |
在创建数据目录锁文件时等待数据到达持久存储。 | |
LockFileCreateWrite |
在创建数据目录锁文件时等待写操作。 | |
LockFileReCheckDataDirRead |
在重新检查数据目录锁文件期间等待读取。 | |
LogicalRewriteCheckpointSync |
等待逻辑重写映射到在检查点到达持久存储。 | |
LogicalRewriteMappingSync |
在逻辑重写期间等待映射数据到达持久存储 | |
LogicalRewriteMappingWrite |
在逻辑重写期间等待映射数据的写入。 | |
LogicalRewriteSync |
等待逻辑重写映射到达持久存储。 | |
LogicalRewriteTruncate |
等待在逻辑重写期间截断映射数据。 | |
LogicalRewriteWrite |
等待逻辑重写映射的写入。 | |
RelationMapRead |
等待关系映射文件的读取。 | |
RelationMapSync |
等待关系映射文件到达持久存储。 | |
RelationMapWrite |
等待对关系映射文件的写入。 | |
ReorderBufferRead |
在重新排序缓冲区管理期间等待读取。 | |
ReorderBufferWrite |
在重新排序缓冲区管理期间等待写操作。 | |
ReorderLogicalMappingRead |
在重新排序缓冲区管理期间等待读取逻辑映射。 | |
ReplicationSlotRead |
等待从复制槽控制文件读取。 | |
ReplicationSlotRestoreSync |
等待复制槽控制文件到达持久存储,同时将其恢复到内存中。 | |
ReplicationSlotSync |
等待复制槽控制文件到达持久存储。 | |
ReplicationSlotWrite |
等待对复制槽控制文件的写入。 | |
SLRUFlushSync |
在检查点或数据库关闭期间等待SLRU数据到达持久存储。 | |
SLRURead |
等待读取SLRU页面。 | |
SLRUSync |
在写页面后等待SLRU数据到达持久存储。 | |
SLRUWrite |
等待SLRU页面的写入。 | |
SnapbuildRead |
等待读取序列化的历史目录快照。 | |
SnapbuildSync |
等待序列化历史目录快照到达持久存储。 | |
SnapbuildWrite |
等待串行历史目录快照的写入。 | |
TimelineHistoryFileSync |
等待通过流复制接收的时间线历史文件到达持久存储。 | |
TimelineHistoryFileWrite |
等待通过流复制接收的时间线历史文件的写入。 | |
TimelineHistoryRead |
等待读取时间线历史文件。 | |
TimelineHistorySync |
等待新创建的时间线历史文件到达持久存储。 | |
TimelineHistoryWrite |
等待写入新创建的时间线历史文件。 | |
TwophaseFileRead |
等待读取两阶段状态文件。 | |
TwophaseFileSync |
等待两阶段状态文件到达持久存储。 | |
TwophaseFileWrite |
等待对两阶段状态文件的写入。 | |
WALBootstrapSync |
在引导过程中等待WAL达到持久存储。 | |
WALBootstrapWrite |
在引导过程中等待WAL页面的写入。 | |
WALCopyRead |
通过复制一个已有WAL段来创建一个新的WAL段时等待读取。 | |
WALCopySync |
等待通过复制已有 WAL 段创建的新 WAL 段写入持久存储。 | |
WALCopyWrite |
通过复制一个已有WAL段来创建一个新的WAL段时等待写入。 | |
WALInitSync |
等待一个新初始化的WAL文件到持久存储。 | |
WALInitWrite |
在初始化一个新的WAL文件时等待写入。 | |
WALRead |
等待WAL文件的读取。 | |
WALSenderTimelineHistoryRead |
在 WAL 发送进程执行时间线命令期间,等待读取时间线历史文件。 | |
WALSyncMethodAssign |
在指派 WAL 同步方法时等待数据写入持久存储。 | |
WALWrite |
等待写入WAL文件。 |
对于扩展注册的轻量级锁切片,名称由扩展指定,并显示为wait_event。用户可能只在某个后端中注册了该切片(通过在动态共享内存中分配),此时其他后端没有这项信息,因此在这种情况下显示extension。
以下示例展示如何查看等待事件:
SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL; pid | wait_event_type | wait_event ------+-----------------+--------------- 2540 | Lock | relation 6644 | LWLock | ProcArrayLock (2 rows)
Table 28.5. pg_stat_replication 视图
| 列 | 类型 | 描述 |
|---|---|---|
pid |
integer |
一个 WAL 发送进程的进程 ID |
usesysid |
oid |
登录到这个 WAL 发送进程的用户的 OID |
usename |
name |
登录到这个 WAL 发送进程的用户的名称 |
application_name |
text |
连接到这个 WAL 发送进程的应用的名称 |
client_addr |
inet |
连接到这个 WAL 发送进程的客户端的 IP 地址。 如果这个域为空,它表示该客户端通过服务器机器上的一个Unix 套接字连接。 |
client_hostname |
text |
已连接的客户端的主机名,由client_addr的反向 DNS 查找报告。 这个字段将只对 IP 连接非空,并且只有 log_hostname被启用时才会非空。 |
client_port |
integer |
客户端用来与这个 WAL 发送进程通讯的 TCP 端口号,如果使用 Unix 套接字则为-1 |
backend_start |
timestamp with time zone |
这个进程开始的时间,即客户端是何时连接到这个WAL 发送进程的。 |
backend_xmin |
xid |
由hot_standby_feedback报告的该备库的xmin视界。 |
state |
text |
当前 WAL 发送进程的状态。可能的值为:
|
sent_lsn |
pg_lsn |
在这个连接上发送的最后一个预写式日志的位置 |
write_lsn |
pg_lsn |
该备库已写入磁盘的最后一个预写式日志位置 |
flush_lsn |
pg_lsn |
该备库已刷入磁盘的最后一个预写式日志位置 |
replay_lsn |
pg_lsn |
已在该备库数据库中重放的最后一个预写式日志位置 |
write_lag |
interval |
从本地刷写最近的 WAL,到收到该备库已写入该 WAL(但尚未刷盘或应用)的通知之间经过的时间。 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_write 所导致的延迟。 |
flush_lag |
interval |
从本地刷写最近的 WAL,到收到该备库已写入并刷写该 WAL(但尚未应用)的通知之间经过的时间。 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 on 所导致的延迟。 |
replay_lag |
interval |
从本地刷写最近的 WAL,到收到该备库已写入、刷写并应用该 WAL 的通知之间经过的时间。 如果该服务器被配置为同步备库,可用此值衡量在提交时 synchronous_commit 级别 remote_apply 所导致的延迟。 |
sync_priority |
integer |
在基于优先级的同步复制中,该备库被选为同步备库的优先级。在基于法定人数的同步复制中,此值不起作用。 |
sync_state |
text |
此备库的同步状态。可能的值为:
|
pg_stat_replication视图为每个 WAL 发送进程包含一行,显示有关复制到该发送进程所连接备库的统计信息。 这里只列出直接连接的备库;不包含下游备库的信息。
pg_stat_replication视图中报告的滞后时间,是最近的 WAL 被写入、刷写和重放,以及发送端获知这些操作完成所花费时间的度量。如果远程服务器被配置为同步备库,这些时间表示各个同步提交级别带来或可能带来的提交延迟。对于异步备库,replay_lag列是最近事务对查询变得可见所需延迟时间的近似值。如果备库已经完全追上发送服务器且没有新的 WAL 活动,系统会在短时间内继续显示最近测得的滞后时间,随后显示为 NULL。
对于物理复制,滞后时间会自动测量。逻辑解码插件可以选择发出跟踪消息;如果没有这样做,跟踪机制会将滞后显示为 NULL。
报告出的滞后时间并不是根据当前重放速率预测该备库还需多久才能追上发送服务器。在持续生成新 WAL 时,那样的系统可能会显示相近的时间;但当发送端空闲时,就会显示不同的值。特别是当备库已经完全追上时,pg_stat_replication显示的是写入、刷写和重放最近报告的 WAL 位置所花费的时间,而不是某些用户可能预期的零。这样做符合为最近写事务测量同步提交和事务可见性延迟的目的。为减少用户因预期另一种滞后模型而产生的混淆,在一个已完全重放且处于空闲状态的系统上,lag 列会在较短时间后恢复为 NULL。监控系统应自行决定将这种情况表示为缺失数据、零,还是继续显示最近一次已知值。
Table 28.6. pg_stat_wal_receiver 视图
| 列 | 类型 | 描述 |
|---|---|---|
pid |
integer |
WAL 接收进程的进程ID |
status |
text |
WAL接收进程的活动状态 |
receive_start_lsn |
pg_lsn |
WAL 接收进程启动时使用的第一个写前日志位置 |
receive_start_tli |
integer |
WAL 接收进程启动时使用的第一个时间线数字 |
received_lsn |
pg_lsn |
已经接收并刷入到磁盘的最后一个预写式日志位置,该字段的初始值是启动WAL 接收进程时使用的第一个日志位置 |
received_tli |
integer |
接收并刷入到磁盘的最后一个预写式日志位置的时间线数字,该字段的初始值为启动WAL 接收进程时使用的第一个日志位置的时间线数字 |
last_msg_send_time |
timestamp with time zone |
从源 WAL 发送进程收到的最后一条消息的发送时间 |
last_msg_receipt_time |
timestamp with time zone |
从源 WAL 发送进程收到的最后一条消息的接收时间 |
latest_end_lsn |
pg_lsn |
向源 WAL 发送进程报告的最后一个预写式日志位置 |
latest_end_time |
timestamp with time zone |
向源 WAL 发送进程报告最后一个预写式日志位置的时间 |
slot_name |
text |
这个WAL 接收进程使用的复制槽的名称 |
conninfo |
text |
这个WAL 接收进程使用的连接字符串,对安全敏感的字段进行了模糊处理。 |
pg_stat_wal_receiver事务只包含一行,它显示了从 WAL 接收进程所连接的服务器得到的有关该接收进程的统计信息。
Table 28.7. pg_stat_subscription 视图
| 列 | 类型 | 描述 |
|---|---|---|
subid |
oid |
订阅的OID |
subname |
text |
订阅的名称 |
pid |
integer |
订阅工作进程的进程 ID |
relid |
Oid |
该工作进程正在同步的关系的 OID;主应用工作进程则为 NULL |
received_lsn |
pg_lsn |
接收到的最后一个预写式日志位置,该字段的初始值为0 |
last_msg_send_time |
timestamp with time zone |
从源 WAL 发送进程收到的最后一条消息的发送时间 |
last_msg_receipt_time |
timestamp with time zone |
从源 WAL 发送进程收到的最后一条消息的接收时间 |
latest_end_lsn |
pg_lsn |
向源 WAL 发送进程报告的最后一个预写式日志位置 |
latest_end_time |
timestamp with time zone |
向 WAL 发送进程报告最后一个预写式日志位置的时间 |
pg_stat_subscription视图为每个订阅的主工作进程包含一行(如果该工作进程未运行,则 PID 为空),并为处理订阅表初始数据复制的工作进程包含额外的行。
Table 28.8. pg_stat_ssl 视图
| 列 | 类型 | 描述 |
|---|---|---|
pid |
integer |
后端或 WAL 发送进程的进程 ID |
ssl |
boolean |
如果在此连接上使用SSL,则为真 |
version |
text |
使用SSL的版本,如果此连接上没有使用SSL则为NULL |
cipher |
text |
正在使用的SSL密码的名称,如果此连接上没有使用SSL则为NULL |
bits |
integer |
使用的加密算法中的位数,如果此连接上没有使用SSL则为NULL |
compression |
boolean |
使用 SSL 压缩时为真,否则为假;如果此连接未使用 SSL,则为 NULL |
clientdn |
text |
区别名称(DN,Distinguished Name)字段与使用的客户端证书,如果没有提供客户端证书或在此连接上没有使用SSL,则为NULL。 如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 |
pg_stat_ssl视图将为每一个后端或者 WAL 发送进程包含一行,用来显示这个连接上的 SSL 使用情况。 可以把它与pg_stat_activity或者pg_stat_replication通过pid列连接来得到更多有关该连接的细节。
Table 28.9. pg_stat_archiver 视图
| 列 | 类型 | 描述 |
|---|---|---|
archived_count |
bigint |
已成功归档的WAL文件数 |
last_archived_wal |
text |
最近成功归档的WAL文件的名称 |
last_archived_time |
timestamp with time zone |
最近成功归档操作的时间 |
failed_count |
bigint |
记录WAL文件归档失败次数 |
last_failed_wal |
text |
最近一次归档操作失败的WAL文件的名称 |
last_failed_time |
timestamp with time zone |
最近一次归档操作失败的时间 |
stats_reset |
timestamp with time zone |
这些统计数据最后一次重置的时间 |
pg_stat_archiver视图总是有一行,其中包含关于集簇的归档进程的数据。
Table 28.10. 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 28.11. 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 28.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视图为每个数据库包含一行,显示备库上因与恢复冲突而取消查询的数据库范围统计信息。由于主库上不会发生这些冲突,该视图只会在备库上包含信息。
Table 28.13. 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 |
更新的行数(包括 HOT 更新的行) |
n_tup_del |
bigint |
删除的行数 |
n_tup_hot_upd |
bigint |
HOT更新的行数(即,不需要单独的索引更新) |
n_live_tup |
bigint |
活的行的估计数量 |
n_dead_tup |
bigint |
死行的估计数量 |
n_mod_since_analyze |
bigint |
自上次分析此表以来修改的行的估计数量 |
last_vacuum |
timestamp with time zone |
最后一次手动清理这个表(不包括VACUUM FULL) |
last_autovacuum |
timestamp with time zone |
这个表最后一次被自动清理守护进程清理的时间 |
last_analyze |
timestamp with time zone |
上一次手动分析这个表 |
last_autoanalyze |
timestamp with time zone |
自动清理守护进程最后一次分析这个表 |
vacuum_count |
bigint |
这个表被手动清理的次数(VACUUM FULL不计数) |
autovacuum_count |
bigint |
这个表被自动清理守护进程清理的次数 |
analyze_count |
bigint |
手动分析这个表的次数 |
autoanalyze_count |
bigint |
这个表被自动清理守护进程分析的次数 |
pg_stat_all_tables视图将为当前数据库中的每一个表(包括 TOAST 表)包含一行,该行显示与对该表的访问相关的统计信息。 pg_stat_user_tables和pg_stat_sys_tables视图包含相同的信息,但是被过滤得分别只显示用户和系统表。
Table 28.14. 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_indexes和pg_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。如果所提供的常量值不在优化器统计信息记录的范围之内,优化器也会访问索引来检查,因为优化器统计信息可能已经“不新鲜”了。
即使不用位图扫描,idx_tup_read和idx_tup_fetch计数也可能不同,因为idx_tup_read统计从该索引取得的索引项而idx_tup_fetch统计从表取得的活着的行。如果使用该索引取得了任何死亡行或还未提交的行,或者如果通过一次只用索引扫描的方式避免了任何堆获取,后者将较小。
Table 28.15. 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_tables和pg_statio_sys_tables视图包含相同的信息,但是被过滤得分别只显示用户表和系统表。
Table 28.16. 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_indexes和pg_statio_sys_indexes视图包含相同的信息,但是被过滤得分别只显示用户索引和系统索引。
Table 28.17. pg_statio_all_sequences 视图
| 列 | 类型 | 描述 |
|---|---|---|
relid |
oid |
序列的OID |
schemaname |
name |
此序列所在的模式的名称 |
relname |
name |
此序列的名称 |
blks_read |
bigint |
从这个序列中读取的磁盘块的数量 |
blks_hit |
bigint |
在此序列中的缓冲区命中数 |
pg_statio_all_sequences视图将为当前数据库中的每个序列包含一行,该行显示在指定序列上有关 I/O 的统计信息。
Table 28.18. 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参数控制到底哪些函数被跟踪。
其他查看统计信息的方法是直接使用查询,这些查询使用上述标准视图用到的底层统计信息访问函数。 如要了解如函数名等细节,可参考标准视图的定义(例如,在psql中你可以发出\d+ pg_stat_activity)。 针对每一个数据库统计信息的访问函数把一个数据库 OID 作为参数来标识要报告哪个数据库。而针对每个表和每个索引的函数要求表或索引 OID。 针对每个函数统计信息的函数用一个函数 OID。注意只有在当前数据库中的表、索引和函数才能被这些函数看到。
与统计收集器相关的其他功能在Table 28.19中列出。
Table 28.19. 附加统计函数
使用pg_stat_reset()还会重置自动清理使用的计数器, 以确定何时触发清理或分析。重置这些计数器可能导致自动清理不执行必要的工作, 这可能会导致问题,如表膨胀或过时的表统计信息。建议在统计信息重置后进行全库ANALYZE。
pg_stat_get_activity是pg_stat_activity视图的底层函数, 它返回一个行集合,其中包含有关每个后端进程所有可用的信息。有时只获得该信息的一个子集可能会更方便。 在那些情况中,可以使用一组更老的针对每个后端的统计访问函数,这些显示在Table 28.20中。 这些访问函数使用一个后端 ID 号,范围从 1 到当前活动后端数目。 函数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 28.20. 按后端统计函数
| 函数 | 返回类型 | 描述 |
|---|---|---|
|
setof integer |
当前活动后端的 ID 编号集合(从 1 到活动后端数) |
|
text |
此后端最近查询的文本 |
|
timestamp with time zone |
最近查询的开始时间 |
|
inet |
连接到此后端的客户端的 IP 地址 |
|
integer |
客户端用于通信的 TCP 端口号 |
|
oid |
这个后端连接到的数据库的OID |
|
integer |
这个后端的进程 ID |
|
timestamp with time zone |
此进程的启动时间 |
|
oid |
登录到这个后端的用户的 OID |
|
text |
如果后端当前正在等待,则为等待事件类型名称,否则为 NULL。详见Table 28.4。 |
|
text |
如果后端当前正在等待,则为等待事件名称,否则为 NULL。详见Table 28.4。 |
|
timestamp with time zone |
当前事务的开始时间 |