PostgreSQL 18 preview - autoprewarm shared buffer预热插件改用流式IO
PostgreSQL 18 preview - autoprewarm shared buffer预热插件改用streaming read I/O
PostgreSQL 18 autoprewarmshared buffer预热插件改用streaming read I/O, 是对 autoprewarm 功能的一个性能优化。它将原来逐个请求数据块加载的方式(调用 ReadBuffer()),改为使用更现代、可能更高效的流式读 I/O API 来批量请求加载属于同一relation(及其不同 fork)的数据块。其目标是利用流式读取的优势,提高预热过程的 I/O 性能,使得数据库在启动或恢复后能更快地将热数据加载到shared buffer达到最佳运行状态。
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d9c7911e1a5f354b7c34b7f53a52e0a690e7ebc9
Use streaming read I/O in autoprewarm
author Melanie Plageman <[email protected]>
Fri, 4 Apr 2025 19:25:45 +0000 (15:25 -0400)
committer Melanie Plageman <[email protected]>
Fri, 4 Apr 2025 19:28:54 +0000 (15:28 -0400)
commit d9c7911e1a5f354b7c34b7f53a52e0a690e7ebc9
tree 10b3ff9fb944649e753a8477067a458edbd89069 tree
parent 6acab8bdbcda735ef47b1bb0ba2284d6c465cd88 commit | diff
Use streaming read I/O in autoprewarm Make a read stream for each valid fork of each valid relation
represented in the autoprewarm dump file and prewarm those blocks
through the read stream API instead of by directly invoking
ReadBuffer().
Co-authored-by: Nazir Bilal Yavuz <[email protected]>
Co-authored-by: Melanie Plageman <[email protected]>
Reviewed-by: Heikki Linnakangas <[email protected]>
Reviewed-by: Daniel Gustafsson <[email protected]>
Reviewed-by: Andrey M. Borodin <[email protected]> (earlier versions)
Reviewed-by: Kirill Reshke <[email protected]> (earlier versions)
Reviewed-by: Matheus Alcantara <[email protected]> (earlier versions)
Discussion: https://postgr.es/m/flat/CAN55FZ3n8Gd%2BhajbL%3D5UkGzu_aHGRqnn%2BxktXq2fuds%3D1AOR6Q%40mail.gmail.com
AI 解读
补丁名称:Use streaming read I/O in autoprewarm (在 autoprewarm 中使用流式读 I/O)
核心内容:
这个补丁改变了 autoprewarm(通常通过 pg_prewarm 扩展实现,并可能自动化执行)加载数据块到 PostgreSQL 共享缓冲区(shared buffers)的方式。
autoprewarm的作用:它的目标是在数据库服务器启动或发生故障转移后,预先将常用的数据块(来自表和索引)加载到内存(共享缓冲区)中。这样可以避免在服务刚恢复时,由于大量缓存未命中(cache miss)导致初始查询性能下降。 它通常通过读取一个之前保存的文件(dump file)来实现,这个文件记录了哪些关系(表、索引等)的哪些数据块是需要预热的。 之前的做法 (问题所在):
旧的实现方式是, autoprewarm逐一读取 dump 文件中记录的每个数据块号。对于每一个块号,它直接调用底层的 ReadBuffer()函数。这个函数的作用是读取一个指定的数据块到共享缓冲区。这种逐块调用 ReadBuffer()的方式,对于操作系统和存储子系统来说,可能表现为一系列分散的、小的读请求,效率不一定最高。新的做法 (这个 Patch 的改进):
补丁修改了这个逻辑。现在, autoprewarm会:
遍历 dump 文件中记录的每个有效的关系(表、索引等)。 对于每个关系的每个有效的数据“分叉”(fork,主要是主数据 fork、空闲空间映射 FSM fork、可见性映射 VM fork. main,fsm,vm),创建一个**读数据流 (read stream)**。通过这个读数据流 API 来请求预热这些数据块,而不是直接为每个块调用 ReadBuffer()。
为什么要做这个改变 (潜在好处)?
提高 I/O 效率: 使用流式读 I/O API 允许 PostgreSQL 的后端以及底层的操作系统更好地优化读取操作。系统现在知道“我要读取这个关系(或其某个 fork)的一系列块”,而不是“给我这个块,再给我那个块”。 更好的 I/O 调度: 这可能使得操作系统能够执行更有效的预读(read-ahead)或者将多个小的读请求合并成更少的、更大的、可能更连续的读请求,从而减少 I/O 开销,提高整体预热速度。 更抽象的接口: 使用流式 API 是一个更高层次的接口,更符合“批量加载数据”的意图。
总结:
这个补丁是对 autoprewarm 功能的一个性能优化。它将原来逐个请求数据块加载的方式(调用 ReadBuffer()),改为使用更现代、可能更高效的流式读 I/O API 来批量请求加载属于同一关系(及其不同 fork)的数据块。其目标是利用流式读取的优势,提高预热过程的 I/O 性能,使得数据库在启动或恢复后能更快地达到最佳运行状态。