PostgreSQL码农集散地

PostgreSQL 18 preview - pg_stat_io "实时"刷新wal sender统计信息

PostgreSQL 18 preview - pg_stat_io "实时"刷新wal sender统计信息

这是 WAL Sender I/O 统计信息实时刷新补丁, backpatch到v16版本.

问题背景: 此前 WAL Sender 进程(负责物理流复制或逻辑复制数据传输的进程),它们只在进程退出时才会将自己产生的 I/O 统计数据更新(刷新)到共享内存中,供 pg_stat_io 查询。这带来一个问题:对于长时间运行的 WAL Sender(这在流复制和逻辑复制场景中非常常见),我们无法在它们运行时实时地、准确地监控它们产生了多少 I/O。必须等到连接断开或进程结束才能看到最终的总量。

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=039549d70f6aa2daa3714a13752a08fa8ca2fb05

Flush the IO statistics of active WAL senders more frequently master github/master  
author Michael Paquier <[email protected]>   
Mon, 7 Apr 2025 22:57:19 +0000 (07:57 +0900)  
committer Michael Paquier <[email protected]>   
Mon, 7 Apr 2025 22:57:19 +0000 (07:57 +0900)  
commit 039549d70f6aa2daa3714a13752a08fa8ca2fb05  
tree 422904486d12deec61e891162d627e57ed40b240 tree  
parent ba2a3c2302f1248496322eba917b17a421499388 commit | diff  
Flush the IO statistics of active WAL senders more frequently  

WAL senders do not flush their statistics until they exit, limiting the  
monitoring possible for live processes.  This is penalizing when WAL  
senders are running for a long time, like in streaming or logical  
replication setups, because it is not possible to know the amount of IO  
they generate while running.  

This commit makes WAL senders more aggressive with their statistics  
flush, using an internal of 1 second, with the flush timing calculated  
based on the existing GetCurrentTimestamp() done before the sleeps done
to waitfor some activity.  Note that the sleep donefor logical and  
physical WAL senders happens in two different code paths, so the stats  
flushes need to happen in these two places.  

One test is added for the physical WAL sender case, and one for the  
logical WAL sender case.  This can be donein a stable fashion by  
relying on the WAL generated by the TAP tests in combination with a  
stats reset while a server is running, but only on HEAD as WAL data has  
been added to pg_stat_io in a051e71e28a1.  

This issue exists since a9c70b46dbe and the introduction of pg_stat_io,  
so backpatch down to v16.  

Author: Bertrand Drouvot <[email protected]>  
Reviewed-by: vignesh C <[email protected]>  
Reviewed-by: Xuneng Zhou <[email protected]>  
Discussion: https://postgr.es/m/[email protected]  
Backpatch-through: 16  

AI 解读

好的,我们来解读一下这个关于 WAL Sender I/O 统计信息刷新的补丁:

补丁核心内容:更频繁地刷新活跃 WAL Sender 的 I/O 统计信息

  • 问题背景 (Problem):

    • PostgreSQL 的 pg_stat_io 视图用于监控不同后端进程产生的 I/O 活动(读/写次数、时间等)。
    • 然而,对于 WAL Sender 进程(负责物理流复制或逻辑复制数据传输的进程),它们只在进程退出时才会将自己产生的 I/O 统计数据更新(刷新)到共享内存中,供 pg_stat_io 查询。
    • 这带来一个问题:对于长时间运行的 WAL Sender(这在流复制和逻辑复制场景中非常常见),我们无法在它们运行时实时地、准确地监控它们产生了多少 I/O。必须等到连接断开或进程结束才能看到最终的总量。
  • 补丁解决方案 (Solution):

    • 这个补丁修改了 WAL Sender 的行为,使其更积极地刷新 I/O 统计信息。
    • 刷新频率: 设定了一个大约 1 秒的内部间隔。
    • 实现机制: 利用了 WAL Sender 在等待新 WAL 记录或活动时已有的休眠 (sleep) 逻辑。在每次准备休眠之前,代码会检查当前时间 (GetCurrentTimestamp()),并基于这个时间戳判断是否需要刷新统计信息。
    • 代码路径: 由于物理复制的 WAL Sender 和逻辑复制的 WAL Sender 在等待/休眠的代码路径上有所不同,因此这个刷新逻辑需要在这两个不同地方分别添加。
  • 测试 (Testing):

    • 为物理 WAL Sender 和逻辑 WAL Sender 分别添加了新的测试用例。
    • 测试方法:依赖于运行 TAP 测试时产生的 WAL 记录,结合在服务器运行时重置统计信息 (pg_stat_reset_shared('io')),然后检查 pg_stat_io 视图中是否能看到活跃 WAL Sender 产生的(非零的)I/O 统计数据。
    • 测试的限制: 这种特定的测试方法依赖于最近 (commit a051e71e28a1) 才加入的功能,即 pg_stat_io 视图能够具体展示 WAL 相关的 I/O。因此,虽然修复本身可以并且将会被反向移植 (backpatch) 到老版本,但这个特定的测试用例只能在开发版本 (HEAD) 上稳定运行。
  • 历史和版本 (History & Versioning):

    • 这个问题自从 pg_stat_io 视图被引入 (commit a9c70b46dbe,对应 PostgreSQL 16 版本) 时就存在了。
    • 因此,这个修复被认为需要反向移植 (backpatch) 到所有受支持的、包含 pg_stat_io 的版本,即从 PostgreSQL 16 开始。

总结和意义:

这个补丁的核心价值在于提升了对活跃复制连接(WAL Sender)的实时监控能力。之前,DBA 无法准确了解一个正在运行的复制连接当前消耗了多少 I/O 资源。通过让 WAL Sender 大约每秒更新一次其在 pg_stat_io 中的统计数据,现在可以更及时地观察和诊断与复制相关的 I/O 性能问题,尤其是在那些需要长时间保持连接的生产环境中。这是一个重要的可观察性 (observability) 改进。