暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL 性能优化(三):BgWriter & WalWriter

原创 言笑 2024-11-07
793

概述

在前面的两篇文章中(PostgreSQL 性能优化(一):vacuum & autovacuumPostgreSQL 性能优化(二):CheckPoint),以 PostgreSQL 的后台进程作为切入点,介绍了 autovacuum 与 checkpoint 的功能及性能优化相关参数,本文将继续围绕可能会导致大量 IO 开销的进程——BgWriter 和 WalWriter 进行性能分析与优化建议,加强对数据库系统从逻辑层面到物理层面的理解。
image.png

BgWriter 介绍

BgWriter 全称 background writer ,即后台写进程,它是一个很重要的后台服务进程。主要作用是将内存中的脏页定期写回磁盘,乍一看同检查点的功能很相似,那么它的存在还有意义吗?

答案是有,而且意义不容忽视。一般情况下,因 BgWriter 会触发得非常频繁,脏页刷盘的动作可以说是持续不断的,由于 BgWriter 减少了内存中脏页的堆积,在下一次检查点触发时,需要处理的脏页数就会减少,从而减轻了 checkpoint 的总压力(检查点通过 checkpoint_completion_target 机制进一步分散瞬时IO压力)。所以两者相辅相成,共同作用于平缓脏数据刷盘的压力,提高业务性能的同时也有助于减少数据库缓冲池中因脏页过多而导致的内存压力,为新的数据页提供更多的缓冲空间。通过系统视图 pg_stat_bgwriter 可以了解两者的性能状态信息。

触发机制:

  • 经过一定时间间隔后周期性刷脏页,由参数 bgwriter_delay 决定
  • 缓冲区中的脏页达到一定比例

相关参数:

  • bgwriter_delay:休眠时间,单位为 ms
  • bgwriter_lru_maxpages:单次写入磁盘的最大脏块数
  • bgwriter_lru_multiplier:一个调整基数。根据 shared_buffers 缓冲区需求量 * bgwriter_lru_multiplier 得到每次实际写回磁盘的脏页数,但是不能超过 bgwriter_lru_maxpages 。所以相对来说,业务高峰期会一次性多处理一点脏块,在非高峰期的写入就“不紧不慢”,表现出了动态调整的作用
  • bgwriter_flush_after:当 bgwriter 累积处理超过此参数设置的脏页量后,尝试发起一次操作系统级别的文件系统缓存刷新操作fsync,强制数据落盘,可以提高数据的持久性。该参数设置太低会出现更频繁的刷新操作,增加磁盘 IO 开销,影响性能;另一方面,可能会使缓冲池中的数据页更快地被标记为干净页,从而可能影响缓冲池的命中率。如果缓冲池命中率下降,数据库可能需要更频繁地从磁盘读取数据,进一步增加磁盘 I/O 压力(同 checkpoint_flush_after )。

BgWriter 性能优化

从上面了解到 BgWriter 的作用后,其确实在一定程度上可以分散 IO 的数据量,但同样也有一个问题,那就是频率带来的影响。众所周知,IO 的压力会受到写入量的多少和频率两个方面的影响,从优化的角度决定了不能仅仅关注某一个方面。

通过增大参数 bgwriter_delay 降低 BgWriter 触发频率对 IO 的影响,合理设置 bgwriter_lru_maxpages、 bgwriter_lru_multiplier 可以控制单次刷盘的脏页数,从而在写入量的角度来分散 IO 的压力。

通过公式:bgwriter_lru_maxpages * 8k * (1s/bgwriter_delay) 估算 bgwriter 在单位时间内刷脏页的效率峰值。可降低 bgwriter_delay 或者调大 bgwriter_lru_maxpages 和 bgwriter_lru_multiplier 来提高 bgwriter 的性能,但是需要注意可能影响到业务性能 。相反,如果觉得 bgwriter 的IO开销影响到了业务的性能,进行适当的反向调整,适当调大bgwriter_flush_after与checkpoint_flush_after。

pg_stat_bgwriter 视图

image.png

  • checkpoints_timed:按时间周期性触发的检查点数量。可以观察检查点是否过于频繁发生,如果数量很高,可能意味着检查点间隔设置得不合理。
  • checkpoints_req:因达到max_wal_size被强制触发的检查点数量。如果这个值过高,可能表明xlog生成较快,观察IO压力适当调整相关参数。
  • checkpoint_write_time:检查点处理脏页写入磁盘的累积总耗时,单位是ms。
  • checkpoint_sync_time:检查点执行强制刷新脏页的累积总耗时,单位是ms,该值不能太高否则应增大checkpoint_flush_after。
  • buffers_checkpoint:由检查点进程 checkpoint 累积处理的脏页数量。可以评估每次检查点写入的数据量大小,判断是否对系统性能产生较大影响。
  • buffers_clean:由后台写进程 bgwriter 累积处理的脏页数量。这个值反映了后台写进程的工作效率,如果该值较低,可能意味着后台写进程没有充分发挥作用,需要考虑调整相关参数如 bgwriter_delay、bgwriter_lru_maxpages 和 bgwriter_lru_multiplier 等。
  • maxwritten_clean:后台写进程在一次运行中写入的最大缓冲区数量。可以与 bgwriter_lru_maxpages 比较,作为判断后台写进程活跃度的一个指标。
  • buffers_backend:由数据库服务器进程 postmaster 累积处理的脏页数量。如果这个值过高,可能表示后端进程在频繁地写入数据,需要进一步分析是哪些查询或操作导致了大量的写入。
  • buffers_backend_fsync:后端进程执行的文件同步操作数量。较高的值可能意味着后端进程在频繁地进行磁盘同步,可能会影响性能。

WalWriter 介绍

Wal 是预写式日志的英文缩写,在 Oracle/MySQL 中别名为redo日志,在 PostgreSQL 中也被称为xlog日志。数据库通过将事务对数据文件的修改提前写入到 wal 日志防止数据丢失,当遇到系统崩溃等故障时,通过实例恢复阶段重新回放 wal 日志实现数据的还原。

WalWriter 进程不停地将 wal(或xlog) 从内存中写入到磁盘,一个事务会产生相应的 xlog 以及脏数据,xlog 的刷盘相较于脏页的刷盘是先完成的,只有当事务完成了提交,此时对应的 xlog 也全部写入到了磁盘,脏页的刷盘可能才会开始。因为对于数据库来说,只要 xlog 没有发生丢失,数据总是可以恢复。

因触发 WalWriter 进程会进行磁盘写操作,意味着会有额外的 IO 开销,通过控制其触发频率等方式实现对 WalWriter 的性能以及额外IO开销的把控。

WalWriter 触发机制:

  • 周期触发:通过参数 wal_writer_delay 设置定期触发的时间间隔,每次触发都会将内存中的 xlog 全部写入到磁盘,然后进入休眠,默认值为200ms,意味着1s可以触发5次。
  • 非周期触发:事务 commit/rollback 会立刻触发,wal_buffer 空间不足为防止覆盖也会立刻触发。

WalWriter 性能优化

  1. 频率的角度:wal_writer_delay、wal_write_flush_after
  2. 量的角度:wal_buffer、wal_level
  3. 安全性角度:fsync、wal_sync_method、full_page_writes、synchronous_commit(可能降低业务性能)
  4. 提交优化:commit_delay & commit_siblings(组提交在业务高峰期下可提高性能)

总结

本文总结了 BgWriter、WalWriter 进程的功能以及通过调整哪些相关参数可以进行性能优化,通过合理调整参数提升后台进程的综合效率是我们的优化目标,优化的结果反过来可以提高业务性能,但是某些不合理或极端的设置在一定程度上甚至会导致业务性能出现下降。

最后修改时间:2024-11-08 13:14:36
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论