Monitoring Database Activity:监控数据库活动
数据库管理员经常想知道:“系统现在在做什么?”本章讨论如何找到答案。
有几种工具可用于监视数据库活动和分析性能。本章的大部分内容都在描述PostgreSQL的累积统计系统,但也不应忽视常规的Unix监控程序,如ps、top、iostat和vmstat。此外,一旦确定了一个性能较差的查询,可能需要使用PostgreSQL的EXPLAIN命令进行进一步的调查。第14.1节讨论了EXPLAIN和理解单个查询行为的其他方法。
在大多数Unix平台上,PostgreSQL根据ps报告修改其命令标题,以便能够很容易地识别各个服务器进程。示例显示如下
$ ps auxww | grep ^postgres
postgres 15551 0.0 0.1 57536 7132 pts/0 S 18:02 0:00 postgres -i
postgres 15554 0.0 0.0 57536 1184 ? Ss 18:02 0:00 postgres: background writer
postgres 15555 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: checkpointer
postgres 15556 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: walwriter
postgres 15557 0.0 0.0 58504 2244 ? Ss 18:02 0:00 postgres: autovacuum launcher
postgres 15582 0.0 0.0 58772 3080 ? Ss 18:04 0:00 postgres: joe runbug 127.0.0.1 idle
postgres 15606 0.0 0.0 58772 3052 ? Ss 18:07 0:00 postgres: tgl regression [local] SELECT waiting
postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl regression [local] idle in transaction
(ps的适当调用在不同的平台上是不同的,正如所示内容的细节一样。这个例子来自最近的一个Linux系统。)这里列出的第一个进程是主服务器进程。为它显示的命令参数与启动它时使用的相同。接下来的四个进程是由主进程自动启动的后台工作进程。(如果你设置系统不运行自动真空,“自动真空启动器”进程将不会出现。)其余的每个进程都是处理一个客户机连接的服务器进程。每个这样的进程在表单中设置其命令行显示。
postgres: user database host activity
在客户端连接的生命周期内,用户、数据库和(客户端)主机项保持不变,但活动指示器会发生变化。活动可以是空闲的(例如,等待客户端命令),在事务中空闲的(在BEGIN块中等待客户端),或者是一个命令类型名称,如SELECT。此外,如果服务器进程当前正在等待另一个会话持有的锁,则会追加等待。在上面的例子中,我们可以推断,进程15606正在等待进程15610完成它的事务,从而释放一些锁。进程15610必须是阻塞器,因为没有其他活动会话。在更复杂的情况下,有必要查看pg_locks系统视图,以确定谁在阻塞谁。)
如果已经配置了cluster_name,集群名称也会显示在ps的输出中:
如果你关闭了update_process_title,那么活动指示器就不会更新;当启动新流程时,流程标题只设置一次。在某些平台上,这可以节省大量的每个命令开销;对另一些人来说,它是微不足道的。
Solaris需要特殊处理。您必须使用/usr/ucb/ps,而不是/bin/ps你还必须使用两个w标志,而不是一个。此外,您对postgres命令的原始调用必须具有比每个服务器进程提供的更短的ps状态显示。如果这三件事都做不到,那么每个服务器进程的ps输出将是原始的postgres命令行。
PostgreSQL的累积统计系统支持收集和报告关于服务器活动的信息。目前,对磁盘块和单行术语中的表和索引的访问都进行了统计。还会计算每个表中的行总数,以及关于每个表的抽真空和分析操作的信息。如果启用,对用户定义函数的调用以及在每个函数中花费的总时间也会被计算在内。
PostgreSQL还支持报告关于当前系统中正在发生什么的动态信息,例如其他服务器进程正在执行的确切命令,以及系统中存在哪些其他连接。这个工具独立于累积统计系统。
由于统计信息的收集增加了查询执行的一些开销,因此可以配置系统收集或不收集信息。这是由通常在postgresql.conf中设置的配置参数控制的。(配置参数设置请参见第20章。)
参数track_activities允许监视任何服务器进程正在执行的当前命令。
参数track_counts控制是否收集关于表和索引访问的累积统计信息。
参数track_functions支持跟踪用户定义函数的使用情况。
参数track_io_timing用于监视块的读和写时间。
参数track_wal_io_timing可以监视WAL写时间。
通常在postgresql.conf中设置这些参数,以便它们适用于所有服务器进程,但也可以使用set命令在单独的会话中打开或关闭它们。(为了防止普通用户向管理员隐藏他们的活动,只有超级用户被允许使用SET更改这些参数。)
累积统计信息在共享内存中收集。每个PostgreSQL进程在本地收集统计信息,然后在适当的时间间隔更新共享数据。当服务器(包括物理副本)完全关闭时,统计数据的永久副本存储在pg_stat子目录中,以便在服务器重新启动时保留统计数据。相反,当从不干净的关机开始时(例如,在立即关机、服务器崩溃、从基本备份和时间点恢复开始),所有统计计数器都将重置。
表28.1中列出的几个预定义视图可用来显示系统的当前状态。还有表28.2中列出的其他几个视图可用于显示累积的统计信息。或者,也可以使用基础的累积统计函数构建自定义视图,如第2.24节所述。
在使用累积统计视图和函数监视收集的数据时,务必认识到信息不会立即更新。每个单独的服务器进程在空闲之前将累积的统计信息刷新到共享内存中,但每PGSTAT_MIN_INTERVAL毫秒(1秒,除非在构建服务器时更改)的频率不会超过一次;因此,仍然在进行的查询或事务不会影响显示的总数,显示的信息滞后于实际活动。但是,由track_activities收集的当前查询信息总是最新的。
另一个要点是,当请求服务器进程显示任何累积的统计信息时,所访问的值将被缓存,直到默认配置中的当前事务结束。因此,只要您继续当前事务,统计信息就会显示静态信息。类似地,当事务中第一次请求任何此类信息时,将收集所有会话的当前查询信息,并且在整个事务中显示相同的信息。这是一个特性,而不是一个bug,因为它允许您对统计数据执行多个查询,并将结果关联起来,而不必担心下面的数字会发生变化。当以交互方式分析统计信息,或使用昂贵的查询时,访问单个统计信息之间的时间增量可能导致缓存统计信息的严重倾斜。为了最小化倾斜,可以将stats_fetch_consistency设置为snapshot,代价是缓存不需要的统计数据会增加内存使用量。相反,如果已知统计信息只被访问一次,那么缓存已访问的统计信息是不必要的,可以通过将stats_fetch_consistency设置为none来避免。您可以调用pg_stat_clear_snapshot()来丢弃当前事务的统计快照或缓存值(如果有的话)。下一次对统计信息的使用(在快照模式下)将导致构建一个新的快照或(在缓存模式下)缓存已访问的统计信息
事务还可以在中查看自己的统计信息(尚未刷新到共享内存统计信息)
视图pg_stat_xact_all_tables、pg_stat_xact_sys_tables、pg_stat_xac d_t_user_tables和pg_stat_xact_user_functions。这些数字的作用并不如所述
以上;相反,它们在整个事务中不断更新。
表28.1所示的动态统计视图中的一些信息受到安全限制。普通用户只能看到关于他们自己的会话(属于他们所属角色的会话)的所有信息。在关于其他会话的行中,许多列将为空。但是请注意,会话的存在及其一般属性(如会话用户和数据库)对所有用户都是可见的。超级用户和具有内置角色pg_read_all_stats(参见第22.5节)特权的角色可以查看所有会话的所有信息。
| View Name【视图名称】 | Description【描述】 |
|---|---|
| pg_stat_activity | 每个服务器流程一行,显示与该流程的当前活动相关的信息,如状态和当前查询。详细信息请参见pg_stat_activity。 |
| pg_stat_replication | 每个WAL发送方进程一行,显示关于复制到该发送方的连接备用服务器的数据。详细信息请参见pg_stat_replication。 |
| pg_stat_wal_receiver | 只有一行,显示来自该接收器所连接的服务器的有关WAL接收器的统计信息。详细信息请参见pg_stat_wal_receiver。 |
| pg_stat_recovery_prefetch | 只有一行,显示恢复期间预取块的统计信息。详细信息请参见pg_stat_recovery_prefetch。 |
| pg_stat_subscription | 每个订阅至少有一行,显示订阅工作者的信息。详细信息请参见pg_stat_subscription。 |
| pg_stat_ssl | 每个连接(常规连接和副本连接)一行,显示关于此连接上使用的SSL的信息。详细信息请参见pg_stat_ssl。 |
| pg_stat_gssapi | 每个连接(常规连接和复制连接)一行,显示该连接上使用的GSSAPI协议和加密信息。详细信息请参见pg_stat_gssapi。 |
| pg_stat_progress_analyze | 每个后端(包括autovacu的工作进程)都有一行运行ANALYZE,显示当前进度。参见第4.1节。 |
| pg_stat_progress_create_index | 每个后端都有一行运行CREATE INDEX或REINDEX,显示当前进度。参见第4.2节。 |
| pg_stat_progress_vacuum | 每个后台(包括autovacu的工作进程)都有一行,显示当前的进度。参见第4.3节 |
| pg_stat_progress_cluster | 每个运行CLUSTER或VACUUM FULL的后端都有一行,显示当前进度。参见第4.4节。 |
| pg_stat_progress_basebackup | 每个WAL发送方进程流都有一行,记录一个基本备份,显示当前进度。参见第4.5节。 |
| pg_stat_progress_copy | 每个后端运行COPY的一行,显示当前进度。参见第4.6节 |
| View Name【视图名称】 | Description【描述】 |
|---|---|
| pg_stat_archiver | 只有一行,显示有关WAL存档进程活动的统计信息。详细信息请参见pg_s tatt_archiver。 |
| pg_stat_bgwriter | 只有一行,显示有关后台地面写入器进程活动的统计信息。详细信息请参见pg_s tatt_bgwriter |
| pg_stat_wal | 只有一行,显示WAL活力的统计数据。详情请参见pg_stat_wal。 |
| pg_stat_database | 每个数据库一行,显示数据库范围的统计信息。详细信息请参见pg_stat_database。 |
| pg_stat_database_conflicts | 每个数据库一行,显示由于与备用服务器上的恢复冲突而取消查询的数据库范围统计信息。详细信息请参见pg_s tatt_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,但统计目前在当前trans - paris action(尚未包含在pg_s ott_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 | 当前数据库中的每个索引都有一行,显示有关该索引的统计信息。详细信息请参见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_seqences。 |
| 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,但只计算当前trans操作期间的调用(尚未包含在pg_stat_user_functions中)。 |
| pg_stat_slru | 每个SLRU一行,显示操作的统计数据。详细信息请参见pg_stat_slru。 |
| pg_stat_replication_slots | 每个复制槽位一行,显示有关复制槽位使用情况的统计信息。详细信息请参见pg_stat_replication_slots。 |
| pg_stat_subscription_stats | 每个订阅一行,显示有关错误的统计信息。详细信息请参见pg_stat_subscription_stats |
每个索引的统计信息对于确定正在使用哪些索引以及它们的有效性特别有用。
pg_statio_view主要用于确定缓冲区缓存的有效性。当实际磁盘读取的数量远远小于缓冲区命中的数量时,则缓存可以满足大多数读请求,而无需调用内核调用。然而,这些统计数据并不能说明全部情况:由于PostgreSQL处理磁盘I/O的方式,不在PostgreSQL缓冲区缓存中的数据可能仍然驻留在内核的I/O缓存中,因此可能不需要物理读取就可以获取数据。有兴趣获得更多关于PostgreSQL I/O行为的详细信息的用户,建议将PostgreSQL统计视图与操作系统实用工具结合使用,以便深入了解内核对I/O的处理。
pg_stat_activity视图对每个服务器进程都有一行,显示与该进程的当前活动相关的信息
表 28.3. pg_stat_activity View
| Column Type | Description【描述】 |
|---|---|
| datid oid | 此后端连接的数据库的OID |
| datname name | 此后端连接到的数据库的名称 |
| pid integer | 后端进程ID |
| leader_pid integer | 如果该进程是并行查询worker,则为并行组长进程ID。如果此进程是并行组长或不参与并行查询,则为NULL。 |
| usesysid oid | 登录到此后端的用户的OID |
| usename name | 登录到此后端的用户名 |
| application_name text | 连接到此后端的应用程序的名称 |
| client_addr inet | 连接到该后端的客户端IP地址。如果该字段为空,则表示客户端是通过服务器机器上的Unix套接字连接的,或者表示这是一个内部进程,例如autovacuum。 |
| client_hostname text | 连接的客户端的主机名,通过反向DNS对客户端(clienten)的解析报告。该字段仅在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_change timestamp with time zone | 最后一次更改状态的时间 |
| wait_event_type text | 后端正在等待的事件类型(如果有的话);否则无效。见表28.4。 |
| wait_event text | 如果后端当前正在等待,则等待事件名称,否则为NULL。请参见表28.5至表28.13。 |
| state text | 此后端当前的总体状态。取值包括: • active: 后端正在执行查询。 • idle: 后端正在等待一个新的客户端命令。 • idle in transaction: 后端位于事务中,但当前没有执行查询 • idle in transaction (aborted): 此状态类似于事务中的空闲状态,只是事务中的一个语句导致了错误。 • fastpath function call: 后端正在执行快速路径函数。 • disabled: 如果在此后端禁用了track_activities,则报告此状态。 |
| backend_xid xid | 此后端的顶层事务标识符(如果有的话)。 |
| backend_xmin xid | 当前后端的xmin水平 |
| query_id bigint | 此后端最近查询的标识符。如果state是活动的,这个字段显示当前执行查询的标识符。在所有其他状态中,它显示执行的最后一个查询的标识符。默认情况下不计算查询标识符,因此该字段将为空,除非启用了compute_query_id参数或配置了计算查询标识符的第三方模块。 |
| query text | 此后端最近查询的文本。如果state是活动的,此字段显示当前正在执行的查询。在所有其他状态中,它显示执行的最后一个查询。默认情况下,查询文本被截断为1024字节;该值可以通过参数track_activity_query_size更改。 |
| backend_type text | 当前后端类型。可能的类型是autovacuum启动器、autovac海量工作器、逻辑复制启动器、逻辑复制海量工作器、并行工作器、后台写入器、客户端后端、检查指针、归档器、启动器、walreceiver、walsender和walwriter。此外,通过扩展注册的后台工作人员可能有额外的类型。 |
wait_event和state列是独立的。如果一个后端处于活动状态,那么它可能正在等待某个事件,也可能没有。如果状态为活动且wait_event为非空,则意味着正在执行查询,但在系统的某个位置被阻塞。
表 28.4. Wait Event Types
| Wait Event Type【等待事件类型】 | Description【描述】 |
|---|---|
| Activity | 服务器进程空闲。此事件类型指示一个进程在其主处理循环中等待活动。Wait_event将标识特定的等待点;见表28.5。 |
| BufferPin | 服务器进程正在等待对数据缓冲区的独占访问。如果另一个进程持有一个开放电流或在查询过程中最后一次从缓冲区读取数据,则缓冲区引脚等待可能会被延长。见表28.6。 |
| Client | 服务器进程正在等待连接到用户应用程序的套接字上的活动。因此,服务器期望发生与它的内部进程无关的事情。Wait_event将标识特定的等待点;见表28.7。 |
| Extension | 服务器进程正在等待扩展模块定义的一些条件。见表28.8。 |
| IO | 服务器进程正在等待一个I/O操作完成。Wait_event将标识特定的等待点;见表28.9。 |
| IPC | 服务器进程正在等待与另一个服务器进程的交互。Wait_event将标识特定的等待点;见表28.10。 |
| Lock | 服务器进程正在等待重量级锁。重量级锁,也称为锁管理器锁或简称锁,主要保护sql可见对象,如表。然而,它们也用于确保某些内部操作(如关系扩展)的互斥性。Wait_event将标识等待的锁的类型;见表28.11。 |
| LWLock | 服务器进程正在等待一个轻量级锁。大多数这样的锁保护共享内存中的特定数据结构。Wait_event将包含一个标识轻量级锁用途的名称。(有些锁有特定的名称;其他的是一组锁的一部分,每个锁都有相似的用途。)见表28.12。 |
| Timeout | 服务器进程正在等待超时过期。Wait_event将标识特定的等待点;见表28.13。 |
表 28.5. Wait Events of Type Activity
| Activity Wait Event【活动等待事件】 | Description【描述】 |
|---|---|
| ArchiverMain | 在存档进程的主循环中等待。 |
| AutoVacuumMain | 在自动真空发射过程的主回路中等待。 |
| BgWriterHibernate | 正在后台写入进程中等待,休眠。 |
| BgWriterMain | 在后台写入进程的主循环中等待。 |
| CheckpointerMain | 在检查指针进程的主循环中等待。 |
| LogicalApplyMain | 在逻辑复制应用程序的主循环中等待。 |
| LogicalLauncherMain | 在逻辑复制启动进程的主循环中等待。 |
| RecoveryWalStream | 在流恢复期间,在启动过程的主循环中等待WAL到达。 |
| SysLoggerMain | 在syslog进程的主循环中等待。 |
| WalReceiverMain | 在WAL接收进程的主循环中等待。 |
| WalSenderMain | 在WAL发送进程的主循环中等待。 |
| WalWriterMain | 在WAL写入进程的主循环中等待。 |
表 28.6. Wait Events of Type BufferPin
| BufferPin Wait Event【等待事件】 | Description【描述】 |
|---|---|
| BufferPin | 等待获取缓冲区上的独占引脚。 |
表 28.7. Wait Events of Type Client
| Client Wait Event【客户端等待事件】 | Description【描述】 |
|---|---|
| ClientRead | 等待从客户端读取数据。 |
| ClientWrite | 等待向客户端写入数据。 |
| GSSOpenServer | 在建立GSSAPI会话时,等待从客户端读取数据。 |
| LibPQWalReceiverConnect | 在WAL接收器中等待建立到远程服务器的连接。 |
| LibPQWalReceiverReceive | 在WAL接收器中等待从远程服务器接收数据。 |
| SSLOpenServer | 尝试连接时正在等待SSL。 |
| WalSenderWaitForWAL | 在WAL发送方进程中等待WAL被刷新。 |
| WalSenderWriteData | 在WAL发送方进程中处理WAL接收方回复时等待任何活动。 |
表 28.8. Wait Events of Type Extension
| Extension Wait Event【扩展等待事件】 | Description【描述】 |
|---|---|
| Extension | 等待获取缓冲区上的独占引脚。 |
表 28.9. Wait Events of Type IO
| IO Wait Event【IO等待事件】 | Description【描述】 |
|---|---|
| BaseBackupRead | 正在等待从文件中读取基本备份。 |
| BufFileRead | 等待从缓冲文件中读取数据。 |
| BufFileWrite | 等待写入缓冲文件。 |
| BufFileTruncate | 等待缓冲文件被截断。 |
| ControlFileRead | 等待从pg_control文件读取。 |
| ControlFileSync | 等待pg_control文件到达持久存储。 |
| ControlFileSyncUpdate | 等待对pg_control文件的更新到达持久存储区。 |
| ControlFileWrite | 等待对pg_control文件的写入。 |
| ControlFileWriteUpdate | 等待写操作来更新pg_control文件。 |
| CopyFileRead | 在文件复制操作期间等待读取。 |
| CopyFileWrite | 在文件复制操作期间等待写入。 |
| DSMFillZeroWrite | 等待用零填充动态共享内存备份文件。 |
| DataFileExtend | 等待关系数据文件被扩展。 |
| DataFileFlush | 等待关系数据文件到达持久存储器。 |
| DataFileImmediateSync | 等待关系数据文件立即同步到持久存储。 |
| DataFilePrefetch | 等待关系数据文件的异步预取。 |
| DataFileRead | 等待从关系数据文件读取。 |
| DataFileSync | 等待关系数据文件的更改到达持久存储器。 |
| DataFileTruncate | 等待关系数据文件被截断。 |
| DataFileWrite | 等待对关系数据文件的写入。 |
| 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 | 等待写入两阶段状态文件。 |
| VersionFileWrite | 在创建数据库时等待写入版本文件。 |
| WALBootstrapSync | 等待WAL在引导期间到达持久存储。 |
| WALBootstrapWrite | 等待在引导过程中写入WAL页。 |
| WALCopyRead | 通过复制现有WAL段创建新的WAL段时,等待读取。 |
| WALCopySync | 等待通过复制现有WAL段创建的新WAL段到达持久存储器。 |
| WALCopyWrite | 通过复制现有WAL段创建新的WAL段时,等待写入。 |
| WALInitSync | 等待新初始化的WAL文件到达持久存储器。 |
| WALInitWrite | 在初始化新的WAL文件时等待写入。 |
| WALRead | 等待从WAL文件中读取。 |
| WALSenderTimelineHistoryRead | 在walsender时间轴命令期间,等待从时间轴历史文件读取。 |
| WALSync | 等待WAL文件到达持久存储器。 |
| WALSyncMethodAssign | 在分配新的WAL同步方法时,等待数据到达持久存储。 |
| WALWrite | 等待对WAL文件的写入。 |
表 28.10. Wait Events of Type IPC
| IPC Wait Event【IPC等待事件】 | Description【描述】 |
|---|---|
| AppendReady | 等待追加计划节点的子计划节点准备就绪。 |
| ArchiveCleanupCommand | 等待archive_cleanup_command完成。 |
| ArchiveCommand | 等待archive_command完成。 |
| BackendTermination | 等待另一个后端终止。 |
| BackupWaitWalArchive | 等待备份所需的WAL文件成功归档。 |
| BgWorkerShutdown | 等待后台工作人员关闭。 |
| BgWorkerStartup | 等待后台工作启动。 |
| BtreePage | 等待继续并行b树扫描所需的页码变为可用。 |
| BufferIO | 等待缓冲区I/O完成。 |
| CheckpointDone | 等待检查点完成。 |
| CheckpointStart | 等待检查点开始。 |
| ExecuteGather | 在执行Gather计划节点时,等待来自子流程的活动。 |
| HashBatchAllocate | 等待被选中的并行哈希参与者分配哈希表。 |
| HashBatchElect | 等待选择并行哈希参与者来分配哈希表。 |
| HashBatchLoad | 等待其他并行哈希参与者完成哈希表的加载。 |
| HashBuildAllocate | 等待被选中的并行哈希参与者分配初始哈希表。 |
| HashBuildElect | 等待选择一个并行哈希参与者来分配初始哈希表。 |
| HashBuildHashInner | 等待其他并行散列参与者完成内部关系的散列。 |
| HashBuildHashOuter | 等待其他并行哈希参与者完成对外部关系的分区。 |
| HashGrowBatchesAllocate | 等待被选中的并行哈希参与者分配更多的批。 |
| HashGrowBatchesDecide | 等待选择并行哈希参与者来决定未来的批处理增长。 |
| HashGrowBatchesElect | 等待选择并行散列参与者以分配更多批。 |
| HashGrowBatchesFinish | 等待一个被选中的并行哈希参与者来决定未来的批处理增长。 |
| HashGrowBatchesRepartition | 等待其他并行哈希参与者完成重分区。 |
| HashGrowBucketsAllocate | 等待被选中的并行哈希参与者完成更多桶的分配。 |
| HashGrowBucketsElect | 等待选择并行哈希参与者来分配更多的桶。 |
| HashGrowBucketsReinsert | 等待其他并行哈希参与者完成将元组插入到新桶中。 |
| LogicalSyncData | 等待逻辑复制远程服务器为初始表同步发送数据。 |
| LogicalSyncStateChange | 等待逻辑复制远程服务器改变状态。 |
| MessageQueueInternal | 等待将另一个进程附加到共享消息队列。 |
| MessageQueuePutMessage | 等待将协议消息写入共享消息队列。 |
| MessageQueueReceive | 等待从共享消息队列接收字节。 |
| MessageQueueSend | 等待向共享消息队列发送字节。 |
| ParallelBitmapScan | 等待并行位图扫描初始化。 |
| ParallelCreateIndexScan | 等待并行CREATE INDEX工作线程完成堆扫描。 |
| ParallelFinish | 等待并行工作者完成计算。 |
| ProcArrayGroupUpdate | 等待组组长在并行操作结束时清除事务ID。 |
| ProcSignalBarrier | 等待一个屏障事件被所有后端处理。 |
| Promote | 等待待机晋升。 |
| RecoveryConflictSnapshot | 等待恢复冲突解决以进行真空清理。 |
| RecoveryConflictTablespace | 等待删除表空间的恢复冲突解决。 |
| RecoveryEndCommand | 等待recovery_end_command完成。 |
| RecoveryPause | 等待恢复恢复。 |
| ReplicationOriginDrop | 等待复制源变为不活动状态,以便将其删除。 |
| ReplicationSlotDrop | 等待复制槽变为非活动状态,以便将其删除。 |
| RestoreCommand | 等待restore_command命令完成。 |
| SafeSnapshot | 等待为只读可延迟事务获取有效快照。 |
| SyncRep | 同步复制期间,等待远程服务器的确认。 |
| WalReceiverExit | 等待WAL接收器退出。 |
| WalReceiverWaitStart | 等待启动进程发送流复制的初始数据。 |
| XactGroupUpdate | 等待组组长在并行操作结束时更新事务状态 |
表 28.11. Wait Events of Type Lock
| Lock Wait Event【锁等待事件】 | Description【描述】 |
|---|---|
| advisory | 正在等待获取建议用户锁。 |
| extend | 等待扩展一个关系。 |
| frozenid | 等待更新pg_database。Datfrozenxid和pg_database.datminmxid。 |
| object | 等待获取非关系数据库对象上的锁。 |
| page | 等待获取关系页上的锁。 |
| relation | 等待获取关系上的锁。 |
| spectoken | 等待获取推测插入锁。 |
| transactionid | 等待事务完成。 |
| tuple | 等待获取元组上的锁。 |
| userlock | 等待获取用户锁。 |
| virtualxid | 等待获取虚拟事务ID锁。 |
表 28.12. Wait Events of Type LWLock
| LWLock Wait Event【LWLock等待事件】 | Description【描述】 |
|---|---|
| AddinShmemInit | 等待管理共享内存中扩展的空间分配。 |
| AutoFile | 正在等待更新postgresql.auto.conf文件。 |
| Autovacuum | 正在等待读取或更新自动抽真空工作器的当前状态。 |
| AutovacuumSchedule | 等待以确保选择为自动真空的表仍然需要真空。 |
| BackgroundWorker | 正在等待读取或更新后台工作程序状态。 |
| BtreeVacuum | 等待读取或更新b树索引的真空相关信息。 |
| BufferContent | 正在等待访问内存中的数据页。 |
| BufferMapping | 正在等待将数据块与缓冲池中的缓冲区相关联。 |
| CheckpointerComm | 正在等待管理fsync请求。 |
| CommitTs | 等待读取或更新事务提交时间戳的最后一个值集。 |
| CommitTsBuffer | 在提交时间戳SLRU缓冲区上等待I/O。 |
| CommitTsSLRU | 等待访问提交时间戳SLRU缓存。 |
| ControlFile | 等待读取或更新pg_control文件或创建一个新的WAL文件。 |
| DynamicSharedMemoryControl | 正在等待读取或更新动态共享内存分配信息。 |
| LockFastPath | 等待读取或更新进程的快速路径锁信息。 |
| LockManager | 正在等待读取或更新有关“重量级”锁的信息。 |
| LogicalRepWorker | 正在等待读取或更新逻辑复制工作者的状态。 |
| MultiXactGen | 正在等待读取或更新共享multixact状态。 |
| MultiXactMemberBuffer | 在multixact成员SLRU缓冲区上等待I/O。 |
| MultiXactMemberSLRU | 等待访问multixact成员SLRU缓存。 |
| MultiXactOffsetBuffer | 在多精确偏移SLRU缓冲区上等待I/O。 |
| MultiXactOffsetSLRU | 等待访问multixact偏移SLRU缓存。 |
| MultiXactTruncation | 正在等待读取或截断多精确动作信息。 |
| NotifyBuffer | 等待I/O的通知消息SLRU缓冲区。 |
| NotifyQueue | 正在等待读取或更新NOTIFY消息。 |
| NotifyQueueTail | 正在等待更新NOTIFY消息存储的限制。 |
| NotifySLRU | 等待访问通知消息SLRU缓存。 |
| OidGen | 等待分配一个新的OID。 |
| OldSnapshotTimeMap | 正在等待读取或更新旧快照控件信息。 |
| ParallelAppend | 在并行附加计划执行期间等待选择下一个子计划。 |
| ParallelHashJoin | 等待在并行哈希连接计划执行期间同步工作者。 |
| ParallelQueryDSA | 等待并行查询动态共享内存分配。 |
| PerSessionDSA | 等待并行查询动态共享内存分配。 |
| PerSessionRecordType | 等待访问关于复合类型的并行查询的信息。 |
| PerSessionRecordTypmod | 等待访问并行查询的关于标识匿名记录类型的类型修饰符的信息。 |
| PerXactPredicateList | 等待在并行查询期间访问由当前可序列化事务持有的谓词锁列表。 |
| PredicateLockManager | 等待访问可序列化事务使用的谓词锁信息。 |
| ProcArray | 等待访问共享的每进程数据结构(通常是获取快照或报告会话的事务ID)。 |
| RelationMapping | 等待读取或更新pg_filenode。映射文件(用于跟踪某些系统编目的文件节点分配)。 |
| RelCacheInit | 等待读取或更新pg_internal。初始化关系缓存初始化文件。 |
| ReplicationOrigin | 正在等待创建、删除或使用复制源。 |
| ReplicationOriginState | 正在等待读取或更新一个复制源的进度。 |
| ReplicationSlotAllocation | 正在等待分配或释放复制槽位。 |
| ReplicationSlotControl | 正在等待读取或更新复制槽位状态。 |
| ReplicationSlotIO | 等待复制槽位上的I/O。 |
| SerialBuffer | 在可序列化事务冲突SLRU缓冲区上等待I/O。 |
| SerializableFinishedList | 等待访问已完成的可序列化事务列表。 |
| SerializablePredicateList | 等待访问由可序列化事务持有的谓词锁列表。 |
| PgStatsDSA | 等待统计动态共享内存分配器访问 |
| PgStatsHash | 等待统计共享内存哈希表访问 |
| PgStatsData | 等待共享内存统计数据访问 |
| SerializableXactHash | 等待读取或更新关于可序列化事务的信息。 |
| SerialSLRU | 等待访问可序列化事务冲突SLRU缓存。 |
| SharedTidBitmap | 在并行位图索引扫描期间,等待访问共享TID位图。 |
| SharedTupleStore | 在并行查询期间等待访问共享元组存储。 |
| ShmemIndex | 等待在共享内存中查找或分配空间。 |
| SInvalRead | 正在等待从共享编目无效队列检索消息。 |
| SInvalWrite | 等待向共享编目无效队列添加消息。 |
| SubtransBuffer | 在子事务SLRU缓冲区上等待I/O。 |
| SubtransSLRU | 等待访问子事务SLRU缓存。 |
| SyncRep | 正在等待读取或更新同步复制状态信息。 |
| SyncScan | 正在等待选择同步表扫描的起始位置。 |
| TablespaceCreate | 正在等待创建或删除表空间。 |
| TwoPhaseState | 等待读取或更新已准备事务的状态。 |
| WALBufMapping | 正在等待替换WAL缓冲区中的页。 |
| WALInsert | 正在等待将WAL数据插入内存缓冲区。 |
| WALWrite | 等待WAL缓冲区写入磁盘。 |
| WrapLimitsVacuum | 正在等待更新事务id和multixact消费的限制。 |
| XactBuffer | 在事务状态SLRU缓冲区上等待I/O。 |
| XactSLRU | 等待访问事务状态SLRU缓存。 |
| XactTruncation | 等待执行pg_xact_status或更新可用的最早事务ID。 |
| XidGen | 等待分配新的事务ID。 |
扩展可以将LWLock类型添加到表28.12所示的列表中。在某些情况下,扩展分配的名称在所有服务器进程中都不可用;因此,LWLock等待事件可能只是报告为“extension”,而不是扩展分配的名称。
表 28.13. Wait Events of Type Timeout
| Timeout Wait Event【超时等待事件】 | Description【描述】 |
|---|---|
| BaseBackupThrottle | 节流活动时在基本备份期间等待。 |
| CheckpointWriteDelay | 执行检查点时在写之间等待。 |
| PgSleep | 由于调用pg_sleep或兄弟函数而等待。 |
| RecoveryApplyDelay | 由于延迟设置,在恢复期间等待应用WAL。 |
| RecoveryRetrieveRetryInterval | 当WAL数据无法从任何源(pg_wal、存档或流)获得时,在恢复期间等待。 |
| RegisterSyncRequest | 向检查指针发送同步请求时等待,因为请求队列已满。 |
| VacuumDelay | 在基于成本的真空延迟点等待。 |
| VacuumTruncate | 等待获取排他锁以截断已真空的表末尾的任何空页。 |
下面是一个如何查看等待事件的例子:
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 | ProcArray |
pg_stat_replication视图将包含每个WAL发送方进程一行,显示有关复制到该发送方连接的备用服务器的统计信息。只列出了直接连接的备用;没有关于下行备用服务器的可用信息。
表 28.14. pg_stat_replication View
| Column Type | Description【描述】 |
|---|---|
| pid integer | WAL发送进程号 |
| usesysid oid | 登录到这个WAL发送进程的用户的OID |
| usename name | 登录到这个WAL发送方进程的用户名 |
| application_name text | 连接到此WAL发送方的应用程序的名称 |
| client_addr inet | 连接到该WAL发送方的客户端的IP地址。如果该字段为空,则表示客户端是通过服务器机器上的Unix套接字连接的。 |
| client_hostname text | 连接的客户端的主机名,由反向DNS查找client_addr报告。该字段仅在IP连接时为非空,且仅在启用log_host @ name时为空。 |
| client_port integer | 客户端用于与此WAL发送方通信的TCP端口号,如果使用Unix套接字,则为-1 |
| backend_start timestamp with time zone | 当这个进程启动的时间,即当客户端连接到这个WAL发送者backend_xmin xid这个备用的xmin水平由hot_standby_feedback报告。 |
| state text | 当前WAL发送方状态。可能的值为 • startup: 这个WAL发送器正在启动。 • catchup: 此WAL发送方连接的备用服务器正在赶上主服务器。 • streaming: 在与之连接的备用服务器赶上主服务器之后,这个WAL发送方将对更改进行流化处理。 • backup: 此WAL发送方正在发送备份。 • stopping: 这个WAL发送器正在停止。 |
| sent_lsn pg_lsn | 在此连接上发送的最后预写日志位置 |
| write_lsn pg_lsn | 此备用服务器将最近的预写日志位置写入磁盘 |
| flush_lsn pg_lsn | 此备用服务器将上一次预写日志位置刷新到磁盘 |
| replay_lsn pg_lsn | 上次预写日志位置重放到此备用服务器上的数据库中 |
| write_lag interval | 从本地刷新最近的WAL到收到备用服务器已写入WAL(但尚未刷新或应用WAL)的通知之间所经过的时间。如果将该服务器配置为同步备用服务器,则可以用它来衡量在提交时synchronous_commit级别remote_write所引起的延迟。 |
| flush_lag interval | 从本地刷新最近的WAL到收到该备用服务器已写入并刷新它(但尚未应用它)的通知之间所经过的时间。如果将该服务器配置为同步备用服务器,则可以用它来衡量在提交时发生的synchronous_commit级别的延迟。 |
| replay_lag interval | 从本地刷新最近的WAL到收到此备用服务器已写入、刷新和应用该WAL的通知之间所经过的时间。如果将该服务器配置为同步备用服务器,则可以用它来衡量synchronous_commit级别remote_apply在提交时产生的延迟。 |
| sync_priority integer | 在基于优先级的同步复制中,选择该备用服务器作为同步备用服务器时的优先级。这在基于仲裁的同步复制中不起作用。 |
| sync_state text | 此备用服务器的同步状态。可能的值为 • async: 这个备用服务器是异步的。 • potential: 这个备用服务器是异步的。这个备用服务器现在是异步的,但是如果当前的一个同步服务器失败,可能会变成同步的。 • sync: 这个备用服务器是同步的。 • quorum: 该备用服务器被视为仲裁备用服务器的候选服务器。 |
| reply_time timestamp with time zone | 从备用服务器收到的最后一个应答消息的发送时间 |
pg_stat_replication视图中报告的滞后时间是最近的WAL被写入、刷新和重放以及发送方了解它所花费的时间的度量值。如果将远程服务器配置为同步备用服务器,这些时间表示每个同步提交级别所引入的(或将引入的)提交延迟。对于异步备用,replay_lag列近似于查询可见最近事务之前的延迟。如果备用服务器完全赶上了发送服务器,并且没有更多的WAL活动,那么最近测量的滞后时间将继续显示一段时间,然后显示NULL。
延迟时间可以自动用于物理复制。逻辑解码插件可以选择性地发出跟踪消息;如果没有,跟踪机制将简单地显示NULL滞后。
报告的延迟时间并不是预测备用服务器需要多长时间才能赶上发送服务器,假设当前重放速度。这样的系统在生成新的WAL时将显示类似的时间,但在发送方变为空闲时将显示不同的时间。特别是,当备用进程完全完成时,pg_stat_replication将显示写入、刷新和重放最近报告的WAL位置所花费的时间,而不是像一些用户可能期望的那样为零。这与测量最近写事务的同步提交和事务可见性延迟的目标一致。为了减少用户对不同延迟模型的困惑,在完全重放的空闲系统上,延迟列在短时间后恢复为NULL。监视系统应该选择是将其表示为缺失数据、零还是继续显示最后的已知值。
pg_stat_replication_slots视图将包含每个逻辑复制槽位一行,显示关于其使用情况的统计信息。
表 28.15. pg_stat_replication_slots View
| Column Type | Description【描述】 |
|---|---|
| slot_name text | 复制槽的惟一、集群范围的标识符 |
| spill_txns bigint | 一旦用于解码来自WAL的更改的逻辑解码使用的内存超过了logical_decoding_work_mem,溢出到磁盘的事务数。对于顶级事务和子事务,计数器都将递增。 |
| spill_count bigint | 在解码该槽位的WAL更改时,事务溢出到磁盘的次数。该计数器在每次溢出事务时递增,同一事务可能被溢出多次。 |
| spill_bytes bigint | 在对该槽位的WAL执行更改解码时溢出到磁盘的已解码事务数据的数量。这个溢出计数器和其他溢出计数器可用于测量逻辑解码期间发生的I/O,并允许调优logical_decoding_work_mem。 |
| stream_txns bigint | 在逻辑解码用于解码该插槽的WAL更改所使用的内存超过logical_decoding_work_mem之后,流到解码输出插件的正在进行的事务的数量。流处理只适用于顶级事务(子事务不能独立地流处理),因此不会为子事务增加计数器。 |
| stream_countbigint | 当从该插槽的WAL解码更改时,正在进行的事务流到解码输出插件的次数。该计数器在每次对事务进行流处理时递增,同一事务可以被流处理多次。 |
| stream_bytesbigint | 当解码从这个槽位的AL发生变化时,为流式处理正在进行的事务而解码到解码输出插件的事务数据量。这个和这个插槽的其他流计数器可用于调优logical_decoding_work_mem。 |
| total_txns bigint | 发送到该插槽的解码输出插件的已解码事务数。这只计算顶层事务,不对子事务进行递增。注意,这包括流和/或溢出的事务。 |
| total_bytesbigint | 当从WAL进行解码更改时,为将事务发送到解码输出插件而解码的事务数据量。注意,这包括流数据和/或溢出数据。 |
| stats_reset timestamp with time zone | 这些统计信息最后一次重置的时间 |
pg_stat_wal_receiver视图将只包含一行,显示来自该接收器所连接的服务器的有关WAL接收器的统计信息。
表 28.16. pg_stat_wal_receiver View
| Column Type | Description【描述】 |
|---|---|
| pid integer | WAL接收进程号 |
| status text | WAL接收方进程的活动状态 |
| receive_start_lsn pg_lsn | WAL接收器启动时使用的第一个预写日志位置 |
| receive_start_tli integer | WAL接收器启动时使用的第一个时间线编号 |
| written_lsn pg_lsn | 上次预写日志位置已接收并写入磁盘,但未刷新。这不应该用于数据完整性检查。 |
| flushed_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接收方使用的复制槽位名称 |
| sender_host text | WAL接收器所连接的PostgreSQL实例的主机。如果是通过Unix套接字连接,则可以是主机名、IP地址或目录路径。(路径大小写可以区分,因为它总是以/开头的绝对路径。) |
| sender_port integer | 该WAL接收器连接的PostgreSQL实例的端口号。 |
| conninfo text | 此WAL接收器使用的连接字符串,对安全敏感的字段进行了模糊处理。 |
pg_stat_recovery_prefetch视图将只包含一行。wal_dis dantame、block_distance和io_depth列显示当前值,其他列显示可以用pg_stat_reset_shared函数重置的cu @ mulative计数器。
表 28.17. pg_stat_recovery_prefetch View
| Column Type | Description【描述】 |
|---|---|
| stats_reset timestamp with time zone | 这些统计信息最后一次重置的时间 |
| prefetch bigint | 预取的块数,因为它们不在缓冲池中 |
| hit bigint | 未预取的块数,因为它们已经在缓冲池中 |
| skip_init bigint | 未预取的块数,因为它们将被零初始化 |
| skip_new bigint | 未预取的块数,因为它们还不存在 |
| skip_fpw bigint | 由于WAL中包含了完整的页面图像,所以未预取的块数 |
| skip_rep bigint | 未预取的块数,因为它们最近已经预取过了 |
| wal_distance int | 预取器向前看了多少字节 |
| block_distance int | 预取器向前看了多少块 |
| io_depth int | 有多少预取已经启动但还不知道已经完成 |
表 28.18. pg_stat_subscription View
| Column Type | Description【描述】 |
|---|---|
| subid oid | 订阅的OID |
| subname name | 订阅的名称 |
| pid integer | 订阅辅助进程的进程ID |
| relid oid | worker正在同步的关系的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_stats视图将为每个订阅包含一行。
表 28.19. pg_stat_subscription_stats View
| Column Type | Description【描述】 |
|---|---|
| subid oid | 订阅的OID |
| subname name | 订阅的名称 |
| apply_error_count bigint | 应用更改时发生错误的次数 |
| sync_error_count bigint | 初始表同步期间发生错误的次数 |
| stats_reset timestamp with time zone | 这些统计信息最后一次重置的时间 |
pg_stat_ssl视图将为每个后端或WAL发送方进程包含一行,显示关于此连接上SSL使用情况的信息。可以将它与pid列上的pg_stat_activity或pg_s tatt_replication连接,以获得有关连接的更多详细信息。
表 28.20. pg_stat_ssl View
| Column Type | Description【描述】 |
|---|---|
| pid integer | 后端进程号或WAL发送进程号 |
| ssl boolean | 如果在此连接上使用SSL,则为True |
| version text | 使用SSL的版本,如果在此连接上没有使用SSL,则为NULL |
| cipher text | 正在使用的SSL密码的名称,如果在此连接上没有使用SSL,则为NULL |
| bits integer | 使用的加密算法中的比特数,如果在此连接上不使用SSL,则为NULL |
| client_dn text | 来自所使用的客户端证书的惟一名称(DN)字段,如果没有提供客户端证书,或者在此连接上没有使用SSL,则为NULL。如果DN字段长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 |
| client_serial numeric | 客户端证书的序列号,如果没有提供客户端证书,或者在此连接上没有使用SSL,则为NULL。证书序列号和证书颁发者的组合唯一标识一个证书(除非颁发者错误地重用了序列号)。 |
| issuer_dn text | 客户端证书颁发者的DN,如果没有提供客户端证书,或者在此连接上没有使用SSL,则为NULL。该字段像client_dn一样被截断 |
pg_stat_gssapi视图将为每个后端包含一行,显示关于此连接上GSSAPI使用情况的信息。可以将它与pid列上的pg_stat_activity或pg_stat_replication连接,以获得有关连接的更多详细信息。
表 28.21. pg_stat_gssapi View
| Column Type | Description【描述】 |
|---|---|
| pid integer | 后端进程ID |
| gss_authenticated boolean | 如果此连接使用GSSAPI身份验证,则为True |
| principal text | Principal用于验证此连接,如果没有使用GSSAPI验证此连接,则为NULL。如果主体长于NAMEDATALEN(标准构建中为64个字符),则该字段将被截断。 |
| encrypted boolean | 如果在此连接上使用GSSAPI加密,则为 |
pg_stat_archiver视图总是只有一行,包含关于集群的存档进程的数据。
表 28.22. pg_stat_archiver View
| Column Type | Description【描述】 |
|---|---|
| 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 | 这些统计信息最后一次重置的时间 |
通常,WAL文件是按从最老到最新的顺序归档的,但这是不能保证的,而且在特殊情况下,如促进待机或崩溃恢复后不保存。因此,假设所有比last_archived_wal更老的文件也已成功归档是不安全的。
pg_stat_bgwriter视图始终只有一行,其中包含集群的全局数据
表 28.23. pg_stat_bgwriter View
| Column Type | Description【描述】 |
|---|---|
| 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_wal视图总是只有一行,包含关于集群WAL活动的数据。
表 28.24. pg_stat_wal View
| Column Type | Description【描述】 |
|---|---|
| wal_records bigint | 生成的WAL记录的总数 |
| wal_fpi bigint | 生成的WAL全页图像的总数 |
| wal_bytes numeric | 以字节为单位生成的WAL总量 |
| wal_buffers_full bigint | 由于WAL缓冲区已满而将WAL数据写入磁盘的次数 |
| wal_write bigint | 通过XLogWrite请求将WAL缓冲区写入磁盘的次数。有关内部WAL函数XLogWrite的更多信息,请参见第30.5节。 |
| wal_sync bigint | 通过issue_xlog_fsync请求将WAL文件同步到磁盘的次数(如果fsync是打开的,wal_sync_method是fdatasync, fsync或fsync_writethrough,否则为零)。有关内部WAL函数issue_xlog_fsync的更多信息,请参见第30.5节。 |
| wal_write_time double precision | 通过XLogWrite请求将WAL缓冲区写入磁盘所花费的总时间,单位为毫秒(如果启用了track_wal_io_timing,则为零)。这包括wal_sync_method为open_datasync或open_sync时的同步时间。 |
| wal_sync_time double precision | 通过issue_xlog_fsync请求将WAL文件同步到磁盘所花费的总时间,以毫秒为单位(如果track_wal_io_timing是启用的,fsync是打开的,wal_sync_method是fdatasync, fsync或fsync_writethrough,否则为零)。 |
| stats_reset timestamp with time zone | 这些统计信息最后一次重置的时间 |
pg_stat_database视图将包含集群中每个数据库的一行,以及共享对象的一行,显示数据库范围的统计信息。
表 28.25. pg_stat_database View
| Column Type | Description【描述】 |
|---|---|
| datid oid | 该数据库的OID,属于共享关系的对象为0 |
| datname name | 此数据库的名称,或共享对象的NULL。 |
| numbackends integer | 当前连接到该数据库的后端数量,或为NULL表示共享对象。这是该视图中唯一返回反映当前状态值的列;所有其他列返回自上次重置以来的累计值。 |
| 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 | 在此数据库中检测到的死锁数量 |
| checksum_failures bigint | 在此数据库中(或在共享对象上)检测到的数据页校验和失败数,如果未启用数据校验和,则为NULL。 |
| checksum_last_failure timestamp with time zone | 在此数据库中(或在共享对象上)检测到最后一次数据页校验和失败的时间,如果未启用数据校验和,则为NULL。 |
| blk_read_time double precision | 后端在此数据库中读取数据文件块所花费的时间,以毫秒为单位(如果启用了track_io_timing,则为零) |
| blk_write_time double precision | 后端在此数据库中写入数据文件块所花费的时间,以毫秒为单位(如果启用了track_io_timing,则为零) |
| session_time double precision | 数据库会话在该数据库中所花费的时间,以毫秒为单位(注意,统计信息仅在会话状态改变时更新,因此如果会话已空闲很长时间,则此空闲时间将不包括在内) |
| active_time double precision | 在此数据库中执行SQL语句所花费的时间,以毫秒为单位(这对应于pg_stat_activity中的状态活动和快速路径函数调用) |
| idle_in_transaction_time double precision | 在此数据库中的事务中闲置的时间,以毫秒为单位(这对应于pg_stat_activity中的事务空闲和事务空闲(已终止)的状态) |
| sessions bigint | 建立到该数据库的总会话数 |
| sessions_abandoned bigint | 由于与客户机的连接丢失而终止的与此数据库的数据库会话数 |
| sessions_fatal bigint | sessions_killed bigint到此数据库的数据库会话因操作员干预而终止的数量 |
| stats_reset timestamp with time zone | 这些统计信息最后一次重置的时间 |
pg_stat_database_conflicts视图将为每个数据库包含一行,显示关于因备用服务器上的恢复冲突而发生的查询取消的base级统计数据。这个视图将只包含备用服务器上的信息,因为主服务器上不会发生冲突。
表 28.26. pg_stat_database_conflicts View
| Column Type | Description【描述】 |
|---|---|
| datid oid | 数据库的OID |
| datname name | 此数据库的名称 |
| confl_tablespace bigint | 此数据库中由于删除表空间而取消的查询数 |
| confl_lock bigint | 此数据库中因锁定超时而取消的查询数 |
| confl_snapshot bigint | 由于旧快照而取消的数据库中查询的数量 |
| confl_bufferpin bigint | 由于固定缓冲区,此数据库中已取消的查询数 |
| confl_deadlock bigint | 此数据库中因死锁而取消的查询数 |
pg_stat_all_tables视图将为当前数据库(包括TOAST表)中的每个表包含一行,显示对该特定表的访问统计信息。视图pg_s 17:tat_user_tables和视图pg_stat_sys_tables包含相同的信息,但是分别仅显示ser表和system表。
表 28.27. pg_stat_all_tables View
| Column Type | Description【描述】 |
|---|---|
| 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 | 自上次分析此表以来修改的估计行数 |
| n_ins_since_vacuum 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 | 最后一次由autovacuum守护进程分析此表 |
| vacuum_count bigint | 该表被手动抽真空的次数(不包括VACUUM FULL) |
| autovacuum_count bigint | autovacuum守护进程对该表进行真空清理的次数 |
| analyze_count bigint | 手动分析该表的次数 |
| autoanalyze_count bigint | autovacuum守护进程分析该表的次数 |
pg_stat_all_indexes视图将为当前数据库中的每个索引包含一行,显示对该特定索引的访问的统计信息。pg_stat_user_indexes和pg_s d_tat_sys_indexes视图包含相同的信息,但分别过滤为只显示用户和系统索引。
表 28.28. pg_stat_all_indexes View
| Column Type | Description【描述】 |
|---|---|
| relid oid | 这个索引的表的OID |
| indexrelid oid | 该索引的OID |
| schemaname name | 此索引所在的模式的名称 |
| relname name | 此索引的表的名称 |
| indexrelname name | 此索引的名称 |
| idx_scan bigint | 在此索引上初始化的索引扫描数 |
| idx_tup_read bigint | 扫描在此索引上返回的索引项的数目 |
| idx_tup_fetch bigint | 使用此索引的简单索引扫描获取的活动表行数 |
索引可以由简单的索引扫描、“位图”索引扫描和优化器使用。在位图扫描中,几个索引的输出可以通过AND或or规则组合,因此在使用位图扫描时,很难将单个堆行获取与特定索引关联起来。因此,位图扫描会增加pg_stat_all_indexes。它使用的索引的Idx_tup_read计数(s),并增加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统计从表中获取的活动行。如果使用索引获取任何死行或尚未提交的行,或者通过仅索引扫描避免任何堆获取,则后者将减少。
pg_statio_all_tables视图将为当前数据库(包括TOAST表)中的每个表包含一行,显示关于该特定表上I/O的统计信息。视图pg_sta _2tio_user_tables和视图pg_statio_sys_tables包含相同的信息,但是分别显示用户表和系统表。
表 28.29. pg_statio_all_tables View
| Column Type | Description【描述】 |
|---|---|
| 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_indexes视图将为当前数据库中的每个索引包含一行,显示关于该特定索引上的I/O的统计信息。pg_statio_user_indexes和pg_statio_sys_indexes视图包含相同的信息,但分别过滤为只显示用户和系统索引
表 28.30. pg_statio_all_indexes View
| Column Type | Description【描述】 |
|---|---|
| relid oid | 这个索引的表的OID |
| indexrelid oid | 该索引的OID |
| schemaname name | 此索引所在的模式的名称 |
| relname name | 此索引的表的名称 |
| indexrelname name | 此索引的名称 |
| idx_blks_read bigint | 从该索引中读取的磁盘块数量 |
| idx_blks_hit bigint | 此索引中的缓冲区命中次数 |
pg_statio_all_sequences视图将为当前数据库中的每个序列包含一行,显示关于该特定序列上的I/O的统计信息。
表 28.31. pg_statio_all_sequences View
| Column Type | Description【描述】 |
|---|---|
| relid oid | 序列的OID |
| schemaname name | 此序列所在的模式的名称 |
| relname name | 此序列的名称 |
| blks_read bigint | 从该序列读取的磁盘块的数量 |
| blks_hit bigint | 在这个序列中缓冲区命中的次数 |
pg_stat_user_functions视图将为每个跟踪的函数包含一行,显示关于该函数执行的统计信息。track_functions参数控制跟踪哪些函数。
表 28.32. pg_stat_user_functions View
| Column Type | Description【描述】 |
|---|---|
| funcid oid | 函数的OID |
| schemaname name | 此函数所在的模式的名称 |
| funcname name | 函数的名称 |
| calls bigint | 调用此函数的次数 |
| total_time double precision | 在这个函数和它调用的所有其他函数上花费的总时间,以毫秒为单位 |
| self_time double precision | 该函数本身花费的总时间(不包括它调用的其他函数),以毫秒为单位 |
PostgreSQL通过SLRU(最近最少使用的简单缓存)访问某些磁盘上的信息。pg_stat_slru视图将为每个跟踪的SLRU缓存包含一行,显示对缓存页面的访问统计信息。
表 28.33. pg_stat_slru View
| Column Type | Description【描述】 |
|---|---|
| name text | SLRU名称 |
| blks_zeroed bigint | 初始化过程中归零的块数 |
| blks_hit bigint | 已经在SLRU中找到磁盘块的次数,因此不需要进行读操作(这只包括在SLRU中的命中,而不包括操作系统的文件系统缓存) |
| blks_read bigint | 为该SLRU读取的磁盘块数量 |
| blks_written bigint | 为该SLRU写入的磁盘块数量 |
| blks_exists bigint | 为这个SLRU检查存在的块的数量 |
| flushes bigint | 此SLRU的脏数据刷新次数 |
| truncates bigint | 此SLRU的截断数 |
| stats_reset timestamp with time zone | 这些统计信息最后一次重置的时间 |
查看统计信息的其他方法可以通过编写使用上面所示的标准视图所使用的相同底层统计信息访问函数的查询来设置。有关函数名称等详细信息,请参阅标准视图的定义。(例如,在psql中,你可以发出\d+pg_stat_activity。)每个数据库统计信息的访问函数采用数据库OID作为参数,以标识要报告的数据库。每个表和每个索引函数接受一个表或索引OID。用于每个函数统计的函数有一个函数OID。注意,只有当前数据库中的表、索引和函数可以通过这些函数看到。
与累积统计系统相关的附加功能如表28.34所示。
表 28.34. Additional Statistics Functions
| Function | Description【描述】 |
|---|---|
| pg_backend_pid () → integer | 返回附加到当前会话的服务器进程的进程ID。 |
| pg_stat_get_activity ( integer ) → setof record | 返回带有指定进程ID的后端信息记录,如果指定NULL,则为系统中的每个活动后端返回一条记录。返回的字段是pg_stat_activity视图中字段的子集。 |
| pg_stat_get_snapshot_timestamp () → timestamp with time zone | 返回当前统计快照的时间戳,如果没有获取统计快照,则返回NULL。如果stats_fetch_consistency设置为snapshot,则在事务中首次访问累积统计信息时进行快照 |
| pg_stat_clear_snapshot () → void | 丢弃当前统计快照或缓存的信息。 |
| pg_stat_reset () → void | 将当前数据库的所有统计计数器重置为零。默认情况下,此函数仅限超级用户使用,但是可以授予其他用户EXECUTE以运行该函数。 |
| pg_stat_reset_shared ( text ) → void | 根据参数的不同,将一些集群范围的统计计数器重置为零。参数可以是bgwriter重置pg_stat_bgwriter视图中的所有计数器,archiver重置pg_stat_archiver视图中的所有计数器,wal重置pg_stat_wal视图中的所有计数器,recovery_prefetch重置pg_stat_recovery_prefetch视图中的所有计数器。默认情况下,此函数仅限超级用户使用,但是可以授予其他用户EXECUTE以运行该函数。 |
| pg_stat_reset_single_table_counters ( oid ) → void | 将当前数据库中的单个表或索引或跨集群中的所有数据库共享的统计信息重置为零。默认情况下,此函数仅限超级用户使用,但是可以授予其他用户EXECUTE以运行该函数。 |
| pg_stat_reset_single_function_counters ( oid ) → void | 将当前数据库中单个函数的统计值重置为零。默认情况下,此函数仅限超级用户使用,但是可以授予其他用户EXECUTE以运行该函数。 |
| pg_stat_reset_slru ( text ) → void | 将单个SLRU缓存或集群中所有SLRU缓存的统计信息重置为零。如果参数为NULL,则重置所有SLRU缓存的pg_stat_slru视图中显示的所有计数器。参数可以是CommitTs、MultiXactMember、MultiXactOffset、Notify、Serial、Subtrans或Xact中的一个,以便仅为该条目重置计数器。如果参数是other(或者确实是任何无法识别的名称),则重置所有其他SLRU缓存(如扩展定义的缓存)的计数器。默认情况下,该函数仅限超级用户使用,但其他用户可以被授予EXECUTE来运行该函数。 |
| pg_stat_reset_replication_slot ( text ) → void | 重置由实参定义的复制槽位的统计信息。如果参数为NULL,则重置所有复制槽位的统计信息。默认情况下,此函数仅限超级用户使用,但是可以授予其他用户EXECUTE以运行该函数。 |
| pg_stat_reset_subscription_stats ( oid ) → void | 将pg_stat_subscription_stats视图中显示的单个订阅的统计信息重置为零。如果参数为NULL,则重置所有订阅的统计信息。默认情况下,此函数仅限超级用户使用,但是可以授予其他用户EXECUTE以运行该函数。 |
使用pg_stat_reset()还会重置autovacuum用来确定何时触发真空或分析的计数器。重置这些计数器可能导致自动真空不执行必要的工作,从而可能导致表膨胀或表统计信息过时等问题。建议在重置统计信息之后进行数据库范围的ANALYZE。
Pg_stat_get_activity是pg_stat_activity视图的基础函数,它返回一组记录,其中包含关于每个后端进程的所有可用信息。有时,只获取这些信息的一个子集可能更方便。在这种情况下,可以使用一组较老的后端统计数据访问函数;表28.35所示。这些访问功能使用后端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;
表 28.35. Per-Backend Statistics Functions
| Function | Description【描述】 |
|---|---|
| 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_wait_event_type ( integer ) → text | 如果此后端当前正在等待,则返回等待事件类型名称,否则返回NULL。详见表28.4。 |
| pg_stat_get_backend_wait_event ( integer ) → text | 如果此后端当前正在等待,则返回等待事件名称,否则返回NULL。请参见表28.5至表28.13。 |
| pg_stat_get_backend_xact_start ( integer ) → timestamp with time | zone 返回后端当前事务启动的时间。 |
监视数据库活动的另一个有用工具是pg_locks系统表。它允许数据库管理员在锁管理器中查看关于未执行锁的信息。例如,这种能力可以用于:
查看当前所有未执行的锁、特定数据库中关系上的所有锁、特定关系上的所有锁或特定PostgreSQL会话持有的所有锁。
确定当前数据库中与最多未授予锁的关系(这可能是数据库客户机之间的争用源)。
确定锁争用对总体数据库性能的影响,以及争用随总体数据库流量的变化程度。
关于pg_locks视图的详细信息见54.12节。关于使用PostgreSQL进行锁和管理并发老化的更多信息,请参阅第13章。
PostgreSQL能够在命令执行过程中报告某些命令的进度。目前,支持进度报告的命令只有ANALYZE、CLUSTER、CREATE INDEX、VACUUM、COPY和BASE_BACKUP(即pg_basebackup发出的用于进行基本备份的复制命令)。这在未来可能会扩大。
当ANALYZE运行时,pg_stat_progress_analyze视图将包含当前运行该命令的每个后端的一行。下表描述了将要报告的信息,并提供了关于如何解释这些信息的信息。
表 28.36. pg_stat_progress_analyze View
| Column Type | Description【描述】 |
|---|---|
| pid integer | 后端进程ID。 |
| datid oid | 此后端连接到的数据库的OID。 |
| datname name | 此后端连接到的数据库的名称。 |
| relid oid | 被分析表的OID。 |
| phase text | 当前处理阶段。见表28.37。 |
| sample_blks_total bigint | 要采样的堆块总数。 |
| sample_blks_scanned bigint | 扫描的堆块数。 |
| ext_stats_total bigint | 扩展统计数。 |
| ext_stats_computed bigint | 计算的扩展统计数。此计数器仅在阶段计算扩展统计信息时前进。 |
| child_tables_total bigint | 子表的数量。 |
| child_tables_done bigint | 扫描的子表数。只有当阶段获取继承的样例行时,此计数器才会前进。 |
| current_child_table_relid oid | 当前正在扫描的子表的OID。此字段仅在phase获取继承的样例行时有效。 |
表 28.37. ANALYZE Phases
| Phase | Description【描述】 |
|---|---|
| initializing | 该命令准备开始扫描堆。预计这一阶段将非常短暂。 |
| acquiring sample rows | 该命令当前正在扫描relid给出的表,以获取样例行。 |
| acquiring inherited sample rows | 该命令当前正在扫描子表以获取样例行。列child_tables_total、child_tables_done和current_child_table_relid包含此阶段的进度信息。 |
| computing statistics | 该命令从表扫描期间获得的样例行计算统计信息。 |
| computing extended statistics | 该命令从表扫描期间获得的样例行计算扩展统计信息。 |
| finalizing analyze | 该命令正在更新pg_class。当这个阶段完成时,ANALYZE将结束 |
注意,当在分区表上运行ANALYZE时,它的所有分区也会被递归分析。在这种情况下,首先为父表报告ANALYZE进度,然后收集它的继承统计信息,然后为每个分区报告。
当CREATE INDEX或REINDEX运行时,pg_stat_progress_create_index视图将包含当前正在创建索引的每个后端的一行。下面的表格记录了将被报告的信息,并提供了如何解释这些信息的信息。
表 28.38. pg_stat_progress_create_index View
| Column Type | Description【描述】 |
|---|---|
| pid integer | 后端进程ID。 |
| datid oid | 此后端连接到的数据库的OID。 |
| datname name | 此后端连接到的数据库的名称。 |
| relid oid | 创建索引的表的OID。 |
| index_relid oid | 正在创建或重建索引的OID。在非并发的CREATE INDEX中,这是0。 |
| command text | 正在运行的命令:CREATE INDEX、CREATE INDEX并发、REINDEX或REINDEX并发。 |
| phase text | 索引创建的当前处理阶段。见表28.39。 |
| lockers_total bigint | 需要等待的储物柜总数,如适用。 |
| lockers_done bigint | 已经等待的储物柜数量。 |
| current_locker_pid bigint | 当前等待的柜子的进程ID。 |
| blocks_total bigint | 当前阶段要处理的块的总数。 |
| blocks_done bigint | 当前阶段已处理的块数。 |
| tuples_total bigint | 当前阶段要处理的元组总数。 |
| tuples_done bigint | 当前阶段已处理的元组数目。 |
| partitions_total bigint | 在分区表上创建索引时,将此列设置为要在其上创建索引的分区总数。在REINDEX期间,该字段为0。 |
| partitions_done bigint | 在分区表上创建索引时,将此列设置为已在其上创建索引的分区数量。在REINDEX期间,该字段为0。 |
表 28.39. CREATE INDEX Phases
| Phase | Description【描述】 |
|---|---|
| initializing | CREATE INDEX或REINDEX准备创建索引。预计这一阶段将非常短暂。 |
| waiting for writers before build | CREATE INDEX并发或REINDEX并发正在等待具有写锁的事务,这些事务可能会看到要完成的表。在非并发模式时将跳过此阶段。列lockers_total、lockers_done和current_locker_pid包含此阶段的进度信息。 |
| building index | 索引由特定于访问方法的代码构建。在此阶段中,支持进度报告的访问方法填充它们自己的进度数据,子阶段在此列中表示。通常,blocks_total和blocks_done将包含进度数据,以及潜在的tuples_total和tuples_done。 |
| waiting for writers before validation | CREATE INDEX并发或REINDEX并发正在等待具有写锁的事务完成,这些事务可能会写入表。在非并发模式时将跳过此阶段。列lockers_total、lockers_done和current_locker_pid包含此阶段的进度信息。 |
| index validation:scanning index | CREATE INDEX concurrent正在扫描索引,搜索需要验证的元组。在非并发模式时将跳过此阶段。列blocks_total(设置为索引的总大小)和blocks_done包含该阶段的进度信息。 |
| index validation: sorting tuples | CREATE INDEX concurrent正在对索引扫描阶段的输出进行排序。 |
| index validation: scanning table | CREATE INDEX concurrent正在扫描表,以验证在前两个阶段收集的索引元组。在非并发模式时将跳过此阶段。列blocks_total(设置为表的总大小)和blocks_done包含该阶段的进度信息。 |
| waiting for old snapshots | CREATE INDEX并发或REINDEX并发正在等待可能看到表的事务释放它们的快照。在非并发模式时将跳过此阶段。列lockers_total、lockers_done和current_locker_pid包含此阶段的进度信息。 |
| waiting for readers before marking dead | REINDEX concurrent正在等待表上具有读锁的事务完成,然后将旧索引标记为死。在非并发模式时将跳过此阶段。列lockers_total、lockers_done和current_locker_pid包含此阶段的进度信息。 |
| waiting for readers before dropping | REINDEX concurrent正在等待表上具有读锁的事务完成,然后再删除旧索引。在非并发模式时将跳过此阶段。列lockers_total、lockers_done和current_locker_pid包含这个ph值的进度信息 |
每当VACUUM正在运行时,pg_stat_progress_vacuum视图将为当前正在抽真空的每个后端(包括autovacuum工作进程)包含一行。这些表描述了将要报告的信息,并提供了如何解释这些信息的信息。VACUUM FULL命令的进度通过pg_stat_progress_cluster报告,因为VACUUM FULL和CLUSTER都重写表,而常规的VACUUM只在适当的位置修改表。参见4.4节。
表 28.40. pg_stat_progress_vacuum View
| Column Type | Description【描述】 |
|---|---|
| pid integer | 后端进程ID。 |
| datid oid | 此后端连接到的数据库的OID。 |
| datname name | 此后端连接到的数据库的名称。 |
| relid oid | 被抽真空表的OID。 |
| phase text | 当前真空处理阶段。见表28.41。 |
| heap_blks_total bigint | 表中堆块的总数。这个数字是在扫描开始时报告的;之后添加的块不会(也不需要)被这个VACUUM访问。 |
| heap_blks_scanned bigint | 扫描的堆块数。因为可见性映射被用来优化扫描,一些块将跳过而不检查;跳过的块包含在这个总数中,因此当真空完成时,这个数字最终将等于heap_blks_total。此计数器仅在相位扫描堆时前进。 |
| heap_blks_vacuumed bigint | 抽真空的堆块数。除非表没有索引,否则此计数器只在该阶段清理堆时前进。不包含死元组的块会被跳过,因此计数器有时会大增量地向前跳过。 |
| index_vacuum_count bigint | 已完成的指数真空循环数。 |
| max_dead_tuples bigint | 根据maintenance_work_mem,在需要执行索引真空循环之前可以存储的死元组的数量。 |
| num_dead_tuples bigint | 自上一个索引真空周期以来收集的死元组数量。 |
表 28.41. VACUUM Phases
| Phase | Description【描述】 |
|---|---|
| initializing | VACUUM准备开始扫描堆。预计这一阶段将非常短暂。 |
| scanning heap | VACUUM当前正在扫描堆。它将修剪和整理每个页面,如果需要,并可能执行冻结活动。heap_blks_scanned列可用于监视扫描的进度。 |
| vacuuming indexes | VACUUM当前正在对索引进行真空清理。如果一个表有任何索引,在堆被完全扫描之后,这种情况至少会发生一次。如果maintenance_work_mem(或者,在autovacuum的情况下,如果设置了autovacuum_work_mem)不足以存储找到的死元组的数量,那么每个真空可能会发生多次。 |
| vacuuming heap | VACUUM当前正在对堆进行真空清理。清理堆与扫描堆不同,它发生在每个清理索引实例之后。如果heap_blks_scanned小于heap_blks_total,则在此阶段结束后,系统将返回扫描堆;否则,它将在此阶段完成后开始清理索引。 |
| cleaning up indexes | VACUUM目前正在清理索引。这发生在完全扫描堆并完成所有索引和堆的抽真空之后。 |
| truncating heap | VACUUM当前正在截断堆,以便在与操作系统的关系的末尾返回空页。这发生在清理索引之后。 |
| performing final cleanup | 吸尘器正在执行最后的清理。在此阶段,VACUUM将清空空闲空间映射,更新pg_class中的统计信息,并向累积统计信息系统报告统计信息。当这个阶段完成时,VACUUM将结束 |
当CLUSTER或VACUUM FULL正在运行时,pg_stat_progress_cluster视图将包含当前正在运行这两个命令的每个后端的一行。下表描述了将要报告的信息,并提供了关于如何解释这些信息的信息。
表 28.42. pg_stat_progress_cluster View
| Column Type | Description【描述】 |
|---|---|
| pid integer | 后端进程ID。 |
| datid oid | 此后端连接到的数据库的OID。 |
| datname name | 此后端连接到的数据库的名称。 |
| relid oid | 被集群表的OID。 |
| command text | 正在运行的命令。或群集或真空满。 |
| phase text | 当前处理阶段。见表28.43。 |
| cluster_index_relid oid | 如果正在使用索引扫描表,这是正在使用的索引的OID;否则,它为零。 |
| heap_tuples_scanned bigint | 扫描的堆元组数。此计数器仅在seq扫描堆、索引扫描堆或写入新堆时前进。 |
| heap_tuples_written bigint | 写入的堆元组数。此计数器仅在seq扫描堆、索引扫描堆或写入新堆时前进。 |
| heap_blks_total bigint | 表中堆块的总数。在seq扫描堆开始时报告此数字。 |
| heap_blks_scanned bigint | 扫描的堆块数。此计数器仅在相位为seq扫描堆时前进。 |
| index_rebuild_count bigint | 重新构建的索引数。此计数器仅在阶段正在重建索引时前进。 |
表 28.43. CLUSTER and VACUUM FULL Phases
| Phase | Description【描述】 |
|---|---|
| initializing | 该命令准备开始扫描堆。预计这一阶段将非常短暂。 |
| seq scanning heap | 该命令当前正在使用顺序扫描的方式扫描表。 |
| index scanning heap | CLUSTER目前正在使用索引扫描扫描表。 |
| sorting tuples | CLUSTER当前正在对元组进行排序。CLUSTER当前正在写新的堆。 |
| swapping relation files | 该命令当前正在将新构建的文件交换到适当的位置。 |
| rebuilding index | 该命令当前正在重建索引。 |
| performing final cleanup | 该命令正在执行最终清理。当此阶段完成时,CLUSTER或VACUUM FULL将结束。 |
当像pg_basebackup这样的应用程序执行基本备份时,pg_s 17:tat_progress_basebackup视图将包含当前正在运行ASE_BACKUP复制命令并流化备份的每个WAL发送方进程的一行。下表描述了将要报告的信息,并提供了关于如何解释这些信息的信息。
表 28.44. pg_stat_progress_basebackup View
| Column Type | Description【描述】 |
|---|---|
| pid integer | WAL发送进程号。 |
| phase text | 当前处理阶段。见表28.45。 |
| backup_total bigint | 将流传输的数据总量。这是在流数据库文件阶段开始时估计和报告的。注意,这只是一个近似值,因为在流数据库文件阶段,数据库可能会改变,WAL日志可能会包括在后面的备份中。一旦流数据量超过了估计的总大小,这个值总是与backup_stream相同。如果在pg_basebackup中禁用估计(即指定——no-estimate-size选项),则该值为NULL。 |
| backup_streamed bigint | 流数据量。此计数器仅在阶段正在流数据库文件或传输wal文件时前进。 |
| tablespaces_total bigint | 要流处理的表空间总数。 |
| tablespaces_streamed bigint | 流表空间的数量。只有当阶段正在流化数据库文件时,此计数器才会前进。 |
表 28.45. Base Backup Phases
| Phase | Description【描述】 |
|---|---|
| initializing | WAL发送方进程准备开始备份。预计这一阶段将非常短暂。 |
| waiting for checkpoint to finish | WAL发送方进程目前正在执行pg_backup_start以准备进行基本备份,并等待开始备份检查点完成。 |
| estimating backup size | WAL发送方进程目前正在估计将作为基本备份流传输的数据库文件的总数。 |
| streaming database files | WAL发送方进程当前正在流化数据库文件作为基本备份。 |
| waiting for wal archiving to finish | WAL发送方进程当前正在执行pg_backup_stop以完成备份,并等待基本备份所需的所有WAL文件成功归档。如果在pg_basebackup中指定了——wal-method=none或——wal-method=stream,备份将在此阶段完成时结束。 |
| transferring wal files | WAL发送方进程当前正在传输备份过程中生成的所有WAL日志。如果在pg_basebackup中指定了——walmethod=fetch,则该阶段发生在等待wal归档完成阶段之后。备份将在此阶段完成时结束。 |
当COPY正在运行时,pg_stat_progress_copy视图将包含当前正在运行COPY命令的每个后端的一行。下表描述了要报告的信息,并提供了关于如何解释这些信息的信息。
表 28.46. pg_stat_progress_copy View
| Column Type | Description【描述】 |
|---|---|
| pid integer | 后端进程ID。 |
| datid oid | 此后端连接到的数据库的OID。 |
| datname name | 此后端连接到的数据库的名称。 |
| relid oid | 执行COPY命令的表的OID。如果从SELECT查询复制,则将其设置为0。 |
| command text | 正在运行的命令:COPY FROM或COPY TO。 |
| type text | 读取或写入数据的io类型:FILE、PROGRAM、PIPE(用于COPY from STDIN和COPY to STDOUT)或CALLBACK(例如在逻辑复制的初始表同步期间使用)。 |
| bytes_processed bigint | COPY命令已处理的字节数。 |
| bytes_total bigint | COPY FROM命令的源文件大小(以字节为单位)。如果不可用,则设置为0。 |
| tuples_processed bigint | COPY命令已处理的元组数目。 |
| tuples_excluded bigint | 因COPY命令的WHERE子句排除而未处理的元组数目。 |
PostgreSQL提供了支持动态跟踪数据库服务器的功能。这允许在代码的特定点调用外部实用程序,从而跟踪执行情况。
许多探测或跟踪点已经插入到源代码中。这些探测旨在供数据库开发人员和管理员使用。默认情况下,探测不会编译到PostgreSQL中;用户需要显式地告诉配置脚本使探测可用。
目前,DTrace1实用程序是受支持的,在撰写本文时,它可用于Solaris、macOS、FreeBSD、NetBSD和Oracle Linux。Linux的SystemTap2项目提供了等效的DTrace,也可以使用。通过更改src/include/utils/probes.h中的宏的定义,理论上可以支持其他动态跟踪实用程序。
默认情况下,探测是不可用的,因此您需要显式地告诉配置脚本使探测在PostgreSQL中可用。要包含DTrace支持,请指定——enable-dtrace命令来配置DTrace。更多信息请参见17.4节。
源代码中提供了许多标准探针,如表28.47所示;表28.48显示了探测中使用的类型。当然可以添加更多的探测来增强PostgreSQL的可观察性。
表 28.47. Built-in DTrace Probes
| Column Type | Description【描述】 |
|---|---|
| transaction-start | 在新事务开始时触发的探测。arg0是事务ID。 |
| transaction-commit | 在事务成功完成时触发的探测。arg0是事务ID。 |
| transaction-abort | 当事务未成功完成时触发的探测。arg0是事务ID。 |
| query-start | 在启动查询处理时触发的探测。Arg0是查询字符串。 |
| query-done | 在查询处理完成时触发的探测。Arg0是查询字符串。 |
| query-parsestart | 在查询解析启动时触发的探测。Arg0是查询字符串。 |
| query-parse-done | 在查询解析完成时触发的探测。Arg0是查询字符串。 |
| query-rewritestart | 在开始重写查询时触发的探测。Arg0是查询字符串。 |
| query-rewritedone | 在查询重写完成时触发的探测。Arg0是查询字符串。 |
| query-plan-start | 在开始规划查询时触发的探测。 |
| query-plan-done | 在查询规划完成时触发的探测。 |
| query-execute-start | 在开始执行查询时触发的探测。 |
| query-execute-done | 在查询执行完成时触发的探测。 |
| statement-status | 在服务器进程更新其pg_stat_activity.status时触发的探测。Arg0是新的状态字符串。 |
| checkpoint-start | 在检查点启动时触发的探测。Arg0持有位标志,用于区分不同的检查点类型,如关机、立即或强制。在检查点完成时触发的探测。(下面列出的探测在检查点处理过程中依次触发)arg0是写入缓冲区的数量。Arg1是缓冲区的总数目。arg2、arg3和arg4分别包含WAL文件的添加、删除和回收的数量 |
| clog-checkpoint-start | 在检查点的CLOG部分启动时触发的探测。Arg0对于正常检查点为true,对于关闭检查点为false。 |
| clog-checkpoint-done | 在检查点的CLOG部分完成时触发的探测。Arg0的含义与阻塞检查点start的含义相同。 |
| subtrans-checkpoint-start | 在检查点的SUBTRANS部分启动时触发的探测。Arg0对于正常检查点为true,对于关闭检查点为false。 |
| subtrans-checkpoint-done | 当检查点的SUBTRANS部分完成时触发的探测。Arg0的含义与子转检查点-start的含义相同。 |
| multixact-checkpoint-start | 当检查点的MultiXact部分启动时触发的探测。Arg0对于正常检查点为true,对于关闭检查点为false。 |
| multixact-checkpoint-done | 当检查点的MultiXact部分完成时触发的探测。Arg0的含义与multixact-checkpoint-start相同。 |
| buffer-checkpoint-start | 在检查点的缓冲区写入部分启动时触发的探测。Arg0持有位标志,用于区分不同的检查点类型,如关机、立即或强制。 |
| buffer-syncstart | 在检查点期间(在确定必须写入哪些缓冲区之后)开始写入脏缓冲区时触发的探测。Arg0是缓冲区的总数。Arg1是当前脏的,需要写入的数字。 |
| buffer-syncwritten | 在检查点期间写入每个缓冲区后触发的探测。arg0是缓冲区的ID号。 |
| buffer-sync-done | 当所有脏缓冲区都已写入时触发的探测。Arg0是缓冲区的总数。Arg1是检查点进程实际写入的缓冲区数量。Arg2是预期写入的数(buffersync-start的arg1);任何差异都反映了检查点期间刷新缓冲区的其他进程。 |
| buffer-checkpoint-sync-start | 在脏缓冲区被写入内核之后,并在开始发出fsync请求之前触发的探测。 |
| buffer-checkpoint-done | 完成将缓冲区同步到磁盘时触发的探测。 |
| twophase-checkpoint-start | 在检查点的两阶段部分启动时触发的探测。 |
| twophase-checkpoint-done | 在检查点的两阶段部分完成时触发的探测。 |
| buffer-readstart | 在启动缓冲区读取时触发的探测。Arg0和arg1包含页面的分叉和块号(但是如果这是一个关系扩展请求,arg1将是-1)。arg2、arg3和arg4包含表空间、数据库和标识关系的关系oid。arg5是为本地缓冲区创建临时关系的后端ID,或为共享缓冲区创建InvalidBackendId(-1)的后端ID。Arg6对于关系扩展请求为真,对于普通读取为假。 |
| buffer-read-done | 在缓冲区读取完成时触发的探测。Arg0和arg1包含页面的分叉和块号(如果这是一个关系扩展请求,arg1现在包含新添加的块的块号)。arg2、arg3和arg4包含表空间、数据库和标识关系的关系oid。arg5是为本地缓冲区创建临时关系的后端ID,或为共享缓冲区创建InvalidBackendId(-1)的后端ID。Arg6对于关系扩展请求为真,对于普通读取为假。如果在池中找到了缓冲区,Arg7为真,否则为假。 |
| buffer-flushstart | 在为共享缓冲区发出任何写请求之前触发的探测。Arg0和arg1包含页面的fork和block号。arg2、arg3和arg4包含表空间、数据库和标识关系的关系oid。 |
| buffer-flushdone | 当写请求完成时触发的探测。(注意,这只是反映了将数据传递给内核的时间;它通常还没有真正写入磁盘。)参数与bufferflush-start相同。 |
| buffer-writedirty-start | 当服务器进程开始写脏缓冲区时触发的探测。(如果这种情况经常发生,这意味着shared_buffers太小或后台写器控制参数需要调整。)arg0和arg1包含页面的fork和block号。arg2、arg3和arg4包含表空间、数据库和标识关系的关系oid。 |
| buffer-writedirty-done | 在完成脏缓冲区写操作时触发的探测。参数与bufferwrite-dirty-start相同。 |
| wal-bufferwrite-dirtystart | 当服务器进程开始写脏WAL缓冲区时触发的探测,因为没有更多的WAL缓冲区空间可用。(如果这种情况经常发生,就意味着wal_buffers太小了。) |
| wal-bufferwrite-dirty-done | 在完成脏WAL缓冲区写操作时触发的探测。 |
| wal-insert | 插入WAL记录时触发的探测。Arg0是记录的资源管理器(rmid)。Arg1包含info标志。WAL -switch()当WAL段开关被请求时触发的探测。 |
| smgr-md-readstart | 在开始从关系读取块时触发的探测。Arg0和arg1包含页面的fork和block号。arg2、arg3和arg4包含表空间、数据库和标识关系的关系oid。arg5是为本地缓冲区创建临时关系的后端ID,或为共享缓冲区创建InvalidBackendId(-1)的后端ID。 |
| smgr-md-readdone | 在块读取完成时触发的探测。Arg0和arg1包含页面的fork和block号。arg2、arg3和arg4包含表空间、数据库和标识关系的关系oid。arg5是为本地缓冲区创建临时关系的后端ID,或为共享缓冲区创建InvalidBackendId(-1)的后端ID。Arg6是实际读取的字节数,而arg7是请求的字节数(如果它们不同,则表示有问题)。 |
| smgr-md-writestart | 在开始向关系写入块时触发的探测。Arg0和arg1包含页面的fork和block号。arg2、arg3和arg4包含表空间、数据库和标识关系的关系oid。arg5是为本地缓冲区创建临时关系的后端ID,或为共享缓冲区创建InvalidBackendId(-1)的后端ID。 |
| smgr-md-writedone | 当块写入完成时触发的探测。Arg0和arg1包含页面的fork和block号。arg2、arg3和arg4包含表空间、数据库和标识关系的关系oid。arg5是为本地缓冲区创建临时关系的后端ID,或为共享缓冲区创建InvalidBackendId(-1)的后端ID。Arg6是实际写入的字节数,而arg7是请求的字节数(如果它们不同,则表示有问题)。 |
| sort-start | 在启动排序操作时触发的探测。Arg0表示堆、索引或数据排序。Arg1对于唯一值实施是正确的。Arg2是键列的个数。Arg3是工作内存允许的千字节数。如果需要对排序结果进行随机访问,Arg4为true。Arg5表示0时为串行,1时为并行worker, 2时为并行leader。 |
| sort-done | 在排序完成时触发的探测。Arg0对于外部排序为真,对于内部排序为假。Arg1是用于外部排序的磁盘块数量,或用于内部排序的千字节内存。 |
| lwlock-acquire | 在获取LWLock时触发的探测。arg0是LWLock的部分。Arg1是请求的锁模式,可以是独占的,也可以是共享的。 |
| lwlock-release | 当LWLock被释放时触发的探测(但请注意,任何被释放的等待器都还没有被唤醒)。arg0是LWLock的部分。 |
| lwlock-waitstart | 当LWLock不能立即可用且服务器进程已开始等待该锁可用时触发的探测。arg0是LWLock的部分。Arg1是请求的锁模式,可以是独占的,也可以是共享的。 |
| lwlock-wait-done | 当服务器进程从等待LWLock(它实际上还没有锁)中释放时触发的探测。arg0是LWLock的部分。Arg1是请求的锁模式,可以是独占的,也可以是共享的。 |
| lwlock-condacquire | 当调用者指定无等待时成功获取LWLock时触发的探测。arg0是LWLock的部分。Arg1是请求的锁模式,可以是独占的,也可以是共享的。 |
| lwlock-condacquire-fail | 当调用者指定不等待而未成功获取LWLock时触发的探测。arg0是LWLock的部分。Arg1是请求的锁模式,可以是独占的,也可以是共享的。 |
| lock-wait-start | 当对重量级锁(lmgr锁)的请求因为锁不可用而开始等待时触发的探测。Arg0到arg3是标识被锁定对象的标记字段。Arg4表示被锁定对象的类型。Arg5表示被请求的锁类型。 |
| lock-wait-done | 当对重量级锁(lmgr锁)的请求完成等待(即已获得锁)时触发的探测。参数与lock-wait-start相同。 |
| deadlock-found | 当死锁检测器发现死锁时触发的探测。 |
表 28.48. Defined Types Used in Probe Parameters
| Type | Description【描述】 |
|---|---|
| LocalTransactionId | unsigned int |
| LWLockMode | int |
| LOCKMODE | int |
| BlockNumber | unsigned int |
| Oid | unsigned int |
| ForkNumber | int |
| bool | unsigned char |
下面的示例显示了一个用于分析系统中事务计数的DTrace脚本,它是在性能测试前后快照pg_stat_database的一个alter & native
#!/usr/sbin/dtrace -qs
postgresql$1:::transaction-start
{
@start["Start"] = count();
self->ts = timestamp;
}
postgresql$1:::transaction-abort
{
@abort["Abort"] = count();
}
postgresql$1:::transaction-commit
/self->ts/
{
@commit["Commit"] = count();
@time["Total time (ns)"] = sum(timestamp - self->ts);
self->ts=0;
}
When executed, the example D script gives output such as:
# ./txn_count.d `pgrep -n postgres` or ./txn_count.d
^C
Start 71
Commit 70
Total time (ns) 2312105013
SystemTap对跟踪脚本使用与DTrace不同的表法,尽管un * *基础跟踪点是兼容的。有一点值得注意,在编写本文时,SystemTap脚本引用探测名称时必须使用双下划线而不是连字符。这预计将在未来的SystemTap版本中得到修复
您应该记住,需要仔细编写和调试DTrace脚本,否则收集的跟踪信息可能没有意义。在大多数情况下,问题出在设备上,而不是底层系统。在讨论使用动态跟踪找到的信息时,一定要附上用于检查和讨论该信息的脚本。发现它是
可以在开发人员希望的任何地方在代码中定义新的探测,尽管这将需要重新编译。下面是插入新探针的步骤:
决定探测名称和要通过探测提供的数据
将探测定义添加到src/backend/utils/probes.d
如果包含探测点的模块中没有pg_trace.h,则包含pg_trace.h,并在源代码中所需的位置插入TRACE_POSTGRESQL探测宏
重新编译并验证新的探测是否可用
下面是一个示例,说明如何按事务ID添加探测来跟踪所有新事务。
决定将探针命名为transaction-start,并需要一个类型为LocalTransactionId的参数
将探针定义添加到src/backend/utils/probes.d:
probe transaction__start(LocalTransactionId);
注意在探测名称中使用了双下划线。在使用探测的DTrace脚本中,双下划线需要替换为连字符,因此transaction-start是为用户编写文档的名称。
TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
| ID | PROVIDER | MODULE | FUNCTION | NAME |
|---|---|---|---|---|
| 18705 | postgresql49878 | postgres | StartTransactionCommand | transaction-start |
| 18755 | postgresql49877 | postgres | StartTransactionCommand | transaction-start |
| 18805 | postgresql49876 | postgres | StartTransactionCommand | transaction-start |
| 18855 | postgresql49875 | postgres | StartTransactionCommand | transaction-start |
| 18986 | postgresql49873 | postgres | StartTransactionCommand | transaction-start |
在向C代码中添加跟踪宏时,有几件事需要注意:
您应该注意为探测的参数指定的数据类型与宏中使用的变量的数据类型相匹配。否则,您将得到编译错误。
在大多数平台上,如果PostgreSQL是用——enable-dtrace构建的,那么跟踪宏的参数将在控制通过宏时被计算,即使没有进行跟踪。如果只是报告几个局部变量的值,这通常不值得担心。但是要注意在参数中调用昂贵的函数。如果需要这样做,请考虑通过检查是否实际启用了跟踪来保护宏
if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED())
TRACE_POSTGRESQL_TRANSACTION_START(some_function(...));
每个跟踪宏都有一个相应的ENABLED宏。