为什么存储RT指标对实例性能影响很大?
文章开始前推荐2个学习环境:
1、欢迎使用镜像快速体验PostgreSQL/DuckDB强大功能:《最好的PostgreSQL学习镜像》
2、欢迎使用云起实验室: 《免费体验PolarDB开源数据库》
3、PolarDB开源数据库内核、应用等学习图谱: https://www.aliyun.com/database/openpolardb/activity
为什么存储RT指标对实例性能影响很大?
https://www.bilibili.com/video/BV1gF411p7hE/
什么样的IO对用户来讲可能是同步IO:
1、事务结束, 等待commit/rollback wal record持久化.
2、SQL要处理的数据(读、修改)不在shared buffer中, 需要从存储读取.
3、当shared buffer的空闲buffer page或干净的有数据buffer page不足时, 同时用户的SQL处理需要从存储载入数据到shared buffer, shared buffer不得不将脏buffer page写入存储, 导致的额外IO. (并且脏页写出前还需要保证这个脏页对应的wal已经持久化. )
什么样的IO对用户来讲可能是异步IO:
1、bgwriter, 后台调度的将shared buffer的脏页写入到存储.
2、checkpoint, 后台调度的将shared buffer的脏页写入到存储.
存储RT指标对实例性能有明显影响的是 同步IO, 对高并发写的小事务影响尤为明显.
社区版本的优化:
1、事务结束, 等待commit/rollback wal record持久化. 优化方式:
存储SSD 页对齐, 同时降低IO擦写量, 同时减少寿命损耗.
降低存储硬件RT
采用组提交.
采用wal异步写, 写入wal buffer就算结束. (数据库崩溃后, 会导致数据丢失. 通常是3倍的wal_writer_delay.)
2、SQL要处理的数据(读、修改)不在shared buffer中, 需要从存储读取. 优化方式:
降低存储硬件RT
提高存储的带宽吞吐
3、当shared buffer的空闲buffer page或干净的有数据buffer page不足时, 同时用户的SQL处理需要从存储载入数据到shared buffer, shared buffer不得不将脏buffer page写入存储, 导致的额外IO. (并且脏页写出前还需要保证这个脏页对应的wal已经持久化. ) 优化方式:
PG社区版本的bgwriter是异步IO, 数据写入操作系统的脏页. 所以社区版本这里基本不需要优化.
但是建议做好系统的 background flush配置, 否则可能引起抖动. (特别是内存很大的主机, 默认是10%脏页才开始刷脏, 可能导致大量操作系统刷脏引起的IO量)
PolarDB的优化:
1、事务结束, 等待commit/rollback wal record持久化. 优化方式:
存储SSD 页对齐, 同时降低IO擦写量, 同时减少寿命损耗.
降低存储硬件RT
但是PolarDB采用共享存储, 链路通常比本地存储长(除非使用支持RDMA的高端设备).
采用组提交.
采用wal异步写, 写入wal buffer就算结束. (数据库崩溃后, 会导致数据丢失. 通常是3倍的wal_writer_delay.)
2、SQL要处理的数据(读、修改)不在shared buffer中, 需要从存储读取. 优化方式:
降低存储硬件RT
但是PolarDB采用共享存储, 链路通常比本地存储长(除非使用支持RDMA的高端设备).
提高存储的带宽吞吐
但是PolarDB采用共享存储, 链路带宽通常比本地存储小(除非使用支持RDMA的高端设备).
3、当shared buffer的空闲buffer page或干净的有数据buffer page不足时, 同时用户的SQL处理需要从存储载入数据到shared buffer, shared buffer不得不将脏buffer page写入存储, 导致的额外IO. (并且脏页写出前还需要保证这个脏页对应的wal已经持久化. ) 优化方式:
PolarDB采用了DIO, 无法进行异步优化. 但是可以增加内存, 同时增加bgwriter调度, 更高效的把脏页刷出, 减少用户进程等待刷脏的几率.
这里PolarDB比社区版本PG对存储RT指标更加敏感. 但是长期来看经过优化应该会超过社区版本, 因为社区版本是double cache存在内存浪费.
也可以通过调整bgwriter的调度参数, 让bgwriter尽可能的把脏页刷出去(bgwriter的动作对用户来讲是异步的), 从而尽量的规避用户请求buffer时没有空闲或干净页的情况. 同时也可以调大shared buffer, 使得尽可能的用更多的shared buffer, 避免用户请求buffer时没有空闲或干净页的情况.
本期问题1:
以下哪些IO属于对数据库性能影响更大的同步IO?
a. 事务结束时, 等待WAL日志持久化
b. bgwriter将脏页写入到存储中
c. 用户请求不到buffer page, 根据LRU算法, 将脏页写入存储
d. 当用户发起SQL请求时, 发现需要访问的数据不在shared buffer内, 从存储读取数据
答案:
acd
解释:
参考本文内容
欢迎关注我的github (https://github.com/digoal/blog) , 学习数据库不迷路.
近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:
文章中的参考文档请点击阅读原文获得.