深入剖析 PostgreSQL 逻辑复制:pg_stat_replication 与 pg_stat_subscription 视图详解
逻辑复制基础回顾
pg_stat_replication 视图详解
pg_stat_subscription 视图详解
结合使用两个视图进行全面监控
总结
PostgreSQL 的逻辑复制功能为数据库管理员 (DBA) 提供了灵活的数据同步解决方案。要有效地监控和排查逻辑复制问题,深入理解 pg_stat_replication
和 pg_stat_subscription
这两个系统视图至关重要。本文将详细解读这两个视图中各个字段的含义,并结合实际案例,阐述如何利用它们进行精细化的监控和故障排查。
逻辑复制基础回顾
在深入探讨这两个视图之前,咱们先简单回顾一下 PostgreSQL 逻辑复制的基本概念。逻辑复制基于发布者 (Publisher) 和订阅者 (Subscriber) 模型。发布者将数据变更(以 WAL 日志的形式)解码为逻辑变更流,订阅者接收并应用这些变更,从而实现数据的同步。这种方式允许用户选择性地复制表或数据库,提供了比物理复制更大的灵活性。
pg_stat_replication 视图详解
pg_stat_replication
视图提供了关于发布者端复制连接的详细信息。它主要关注的是从发布者到订阅者的连接状态和数据流。每个连接对应视图中的一行。
注意: 要查看此视图,你需要具有 pg_monitor
或超级用户权限。
下面是 pg_stat_replication
视图中各个字段的详细解释:
字段名 | 数据类型 | 描述 |
---|---|---|
pid | integer | 与此发布者关联的 walsender 进程的进程 ID。 |
usesysid | oid | 连接到此 walsender 的用户的 OID。 |
usename | name | 连接到此 walsender 的用户的名称。 |
application_name | text | 连接到此 walsender 的应用程序的名称(通常是订阅者的名称)。 |
client_addr | inet | 连接到此 walsender 的客户端的 IP 地址。如果此 walsender 是通过 Unix 域套接字连接的,则此列为空。 |
client_hostname | text | 连接到此 walsender 的客户端的主机名(如果可用)。如果此 walsender 是通过 Unix 域套接字连接的,或者主机名查找被禁用,则此列为空。 |
client_port | integer | 连接到此 walsender 的客户端的 TCP 端口号。如果此 walsender 是通过 Unix 域套接字连接的,则此列为 -1。 |
backend_start | timestamp with time zone | 此 walsender 进程启动的时间。 |
backend_xmin | xid | 此连接的 Horizon 之前的最早的事务 ID。这可以用来确定可以从发布服务器上安全删除的旧 WAL 日志的年龄。 |
state | text | 此 walsender 进程的当前状态。可能的值为:startup 、catchup 、streaming 、backup 和 stopping 。 |
sent_lsn | pg_lsn | 此 walsender 进程发送的最后一个 WAL 位置。 |
write_lsn | pg_lsn | 此 walsender 进程写入磁盘的最后一个 WAL 位置。 |
flush_lsn | pg_lsn | 此 walsender 进程刷新到磁盘的最后一个 WAL 位置。 |
replay_lsn | pg_lsn | 此 walsender 进程报告给发布服务器的最后一个 WAL 位置(即订阅服务器已经接收、持久化并应用的)。 |
write_lag | interval | 从将 WAL 写入本地磁盘到接收到此 walsender 进程的最新通知之间的时间。这可以用来衡量复制延迟,包括网络延迟和订阅服务器将 WAL 写入其本地磁盘的延迟。 |
flush_lag | interval | 从将 WAL 刷新到本地磁盘到接收到此 walsender 进程的最新通知之间的时间。这可以用来衡量复制延迟,包括网络延迟和订阅服务器将 WAL 刷新到其本地磁盘的延迟。 |
replay_lag | interval | 从将 WAL 应用到订阅服务器到接收到此 walsender 进程的最新通知之间的时间。这可以用来衡量复制延迟,包括网络延迟和订阅服务器应用 WAL 的延迟。 |
sync_priority | integer | 此订阅的同步优先级。值越小,优先级越高。 |
sync_state | text | 此订阅的同步状态。可能的值为:async 、sync 和 quorum 。 |
reply_time | timestamp with time zone | 此 walsender 进程接收到来自订阅服务器的最新回复的时间。 |
重点字段解读与应用:
state
字段: 反映了复制连接的当前状态。通常情况下,我们期望看到streaming
状态,表示数据正在实时流式传输。如果状态为startup
或catchup
,则表明订阅者正在追赶发布者的进度。backup
状态通常表示订阅者正在执行基础备份。stopping
状态则表示连接正在关闭。sent_lsn
、write_lsn
、flush_lsn
和replay_lsn
: 这四个字段是监控复制延迟的关键。sent_lsn
表示发布者已经发送的 WAL 位置,replay_lsn
表示订阅者已经应用的 WAL 位置。它们之间的差距(replay_lag
)反映了复制的总体延迟。write_lsn
和flush_lsn
则分别表示发布者将 WAL 写入和刷新到磁盘的位置,可以用来分析发布者端的性能瓶颈。*_lag
字段:write_lag
、flush_lag
和replay_lag
直接以时间间隔的形式展示了不同阶段的延迟,更直观地反映了复制的实时性。sync_priority
和sync_state
: 用于同步复制。当synchronous_commit
设置为on
、remote_apply
、remote_write
、local
或off
时,同步复制才起作用。sync_state
显示了同步状态,sync_priority
决定了同步订阅者的优先级。
示例场景:
假设你发现某个订阅者的 replay_lag
持续增长,而 write_lag
和 flush_lag
相对较小。这表明问题可能出在订阅者端,可能是订阅者服务器资源不足,或者应用 WAL 的速度跟不上接收速度。
pg_stat_subscription 视图详解
pg_stat_subscription
视图提供了关于订阅者端逻辑复制订阅的详细信息。每个订阅对应视图中的一行。与pg_stat_replication
不同,pg_stat_subscription
关注的是订阅者如何接收和应用来自发布者的数据。
注意: 要查看此视图,你需要具有 pg_monitor
或超级用户权限, 或者订阅的所有者。
下面是 pg_stat_subscription
视图中各个字段的详细解释:
字段名 | 数据类型 | 描述 |
---|---|---|
subid | oid | 订阅的 OID。 |
subname | name | 订阅的名称。 |
pid | integer | 订阅的 apply worker 进程的进程 ID。如果 worker 未运行,则此列为空。 |
relid | oid | 如果此 worker 正在同步表,则为表的 OID;否则为空。 |
received_lsn | pg_lsn | 从此发布者接收的最后一个 WAL 位置。 |
last_msg_send_time | timestamp with time zone | 从此发布者接收到的最后一条消息的发送时间。 |
last_msg_receipt_time | timestamp with time zone | 从此发布者接收到的最后一条消息的接收时间。 |
latest_end_lsn | pg_lsn | 报告给发布服务器的最后一个 WAL 位置(即订阅服务器已经接收、持久化并应用的)。 |
latest_end_time | timestamp with time zone | 报告给发布服务器的最后一个 WAL 位置的时间。 |
重点字段解读与应用:
pid
和relid
:pid
字段显示了 apply worker 进程的 ID,可以用来监控 worker 进程的状态。如果pid
为空,则表示 worker 进程未运行,可能是订阅被禁用或者出现了错误。relid
字段显示了当前正在同步的表的 OID,有助于了解同步的进度。received_lsn
和latest_end_lsn
:received_lsn
表示订阅者已经从发布者接收到的 WAL 位置,latest_end_lsn
表示订阅者已经应用的 WAL 位置。它们之间的差距可以反映订阅者端的应用延迟。last_msg_send_time
和last_msg_receipt_time
: 这两个字段可以用来计算网络延迟。last_msg_receipt_time
-last_msg_send_time
的结果就是网络传输消息所需的时间。
示例场景:
如果你发现某个订阅的 received_lsn
和 latest_end_lsn
之间的差距持续扩大,而 last_msg_send_time
和 last_msg_receipt_time
之间的差距相对稳定。这表明网络传输正常,问题可能出在订阅者应用 WAL 的速度上。你需要检查订阅者服务器的资源使用情况,或者查看是否有长时间运行的事务阻塞了 WAL 的应用。
结合使用两个视图进行全面监控
pg_stat_replication
和 pg_stat_subscription
视图提供了互补的信息。pg_stat_replication
关注发布者端的连接和发送状态,而 pg_stat_subscription
关注订阅者端的接收和应用状态。将这两个视图结合起来,可以更全面地了解逻辑复制的整体情况,更准确地定位问题。
以下是一些建议的监控策略:
- 监控复制延迟: 定期检查
pg_stat_replication
中的replay_lag
和pg_stat_subscription
中received_lsn
与latest_end_lsn
的差距。设置合理的阈值,并在延迟超过阈值时发出警报。 - 监控连接状态: 检查
pg_stat_replication
中的state
字段,确保复制连接处于streaming
状态。如果出现其他状态,需要及时调查原因。 - 监控 worker 进程: 检查
pg_stat_subscription
中的pid
字段,确保 apply worker 进程正在运行。如果pid
为空,需要检查订阅的状态和错误日志。 - 监控网络延迟: 计算
pg_stat_subscription
中last_msg_receipt_time
和last_msg_send_time
的差值,监控网络传输的延迟。 - 分析性能瓶颈: 结合
pg_stat_replication
中的sent_lsn
、write_lsn
、flush_lsn
和replay_lsn
,以及pg_stat_subscription
中的received_lsn
和latest_end_lsn
,分析复制过程中的性能瓶颈是出现在发布者端、网络传输还是订阅者端。 - 同步复制监控: 结合
pg_stat_replication
中sync_state
和sync_priority
,来确定同步复制是否按预期工作。当sync_state
不是sync
或quorum
时,表示同步复制可能存在问题。
总结
pg_stat_replication
和 pg_stat_subscription
是 PostgreSQL 逻辑复制监控和故障排查的重要工具。通过深入理解这两个视图中各个字段的含义,并结合实际场景进行分析,DBA 可以更有效地管理逻辑复制,确保数据的及时同步和系统的稳定运行。希望本文能帮助你更好地掌握 PostgreSQL 逻辑复制的监控和调优。记住,实践出真知,多动手操作,多观察,你就能成为 PostgreSQL 逻辑复制的专家!
补充说明:
除了这两个视图,PostgreSQL 还提供了一些其他的工具和函数,可以用来监控和管理逻辑复制,例如:
pg_replication_slots
视图: 显示复制槽的信息,复制槽用于确保发布者不会删除订阅者仍然需要的 WAL 日志。pg_logical_slot_get_changes()
函数: 可以用来手动读取逻辑复制槽中的变更。pg_create_logical_replication_slot()
函数: 用于创建逻辑复制槽。pg_drop_replication_slot()
函数: 用于删除逻辑复制槽。
掌握这些工具和函数,可以进一步提升你对 PostgreSQL 逻辑复制的掌控能力。