Persisted Buffer Pool(PBP)特性能够帮助您在集群异常退出或者重新启动时,仍然可以使用集群退出前的Shared Buffer Pool。
前提条件
支持的PolarDB PostgreSQL版的版本如下:
PostgreSQL 14(内核小版本14.5.2.0及以上)
PostgreSQL 11(内核小版本1.1.1及以上)
您可通过如下语句查看PolarDB PostgreSQL版的内核小版本的版本号:
PostgreSQL 14
select version();
PostgreSQL 11
show polar_version;
背景信息
PolarDB PostgreSQL版的内存可以分为Shared Buffer Pool、Dynamic Shared Memory Areas以及进程私有内存三部分:
Shared Buffer Pool:集群启动时采用预分配的方式建立的一大段共享内存,通过确定offset来对各个功能模块划分使用区间。
Dynamic Shared Memory Areas:进程间动态共享内存区。PostgreSQL为实现进程间并行计算设计的共享内存区,可以动态扩展。
Process Global Area:进程工作使用的内存区。包含以下两部分。
Memory Context。
逻辑直接控制的内存。
内存划分如图所示:
其中,Shared Buffer Pools在PolarDB PostgreSQL版中使用的内存最多,且对性能有直接影响。原PostgreSQL在集群重启或者意外退出时,都会对Shared Buffer Pools进行清理和重新初始化。在集群重启进入到故障恢复状态时,会根据WAL日志进行数据页面的修改,需要重新加载数据甚至修改数据,影响集群可用时间。其次,Shared Buffer Pools的重新初始化将会导致重新加载数据业务需要的数据,会带来严重的性能抖动。
为了解决以上问题,PolarDB PostgreSQL版增加了Persisted Buffer Pool(PBP)的特性,能够在集群异常退出或者重新启动时,仍然可以使用集群退出前的Shared Buffer Pool。优势如下:
减少故障恢复时间,提升系统可用性。
集群退出前后,性能没有明显抖动。
原理介绍
PolarDB PostgreSQL版将Shared Buffer Pool的部分内存变为Pod级生命周期的Persisted Buffer Pool。根据对性能的影响性,PolarDB PostgreSQL版主要将Buffer Pool和Buffer Descriptor两部分放入了PBP中,其他依旧是Instance级生命周期的内存。
Pod级生命周期:PolarDB PostgreSQL版是部署在K8s上的,Pod级生命周期的共享内存不会随着集群的退出而销毁。
Instance级生命周期:在集群退出或者异常退出重启后进行清理的集群级共享内存。
内存划分如图所示:
影响PBP可用性的指标
集群退出前的PBP不是所有场景都适用。在集群启动时,如果出现以下情况,则无法使用PBP。
集群的规格改变,需要使用不同大小的Buffer Pool。
当前PBP并非此集群所建立。
当前PBP中的控制信息失效。
除了PBP的整体可用性需要检查外,每个PBP的页都需要做可用性检测。如果出现以下情况,则无法使用当前页。
当前页存在未提交的事务。
当前页的Descriptor信息无效。
当前页存在无效的LSN。
当前页的属性为错误或者无效。
影响PBP可用性的指标如图所示:
PBP的效果
Persisted Buffer Pool在数据库重启后,依然能够使用集群退出前的Buffer Pool。因此,无论在恢复场景还是业务场景,都能够快速使用缓存数据,提升性能。如图所示:
恢复性能对比。
模拟异常退出时的场景,回放日志总大小为2093 MB情况如下:
参数
日志回放耗时
故障恢复耗时
未使用PBP
598s
746s
使用PBP
68s
294s
耗时对比如图所示:
性能前后对比。
并不是Buffer Pool中所有的页都是可以复用的。例如:在重启前,某进程对页上X锁,随后系统宕机了,该X锁就没有进程来释放了。因此,在宕机和重启之后需要把Buffer Pool的所有页遍历一遍,剔除掉不能被复用的页。另外,Buffer Pool的回收依赖于K8s。使用该优化之后,可以使重启前后的性能更加平稳。重启前后性能对比如图所示:
使用指南
打开如下参数即可使用。
polar_enable_persisted_buffer_pool = ON
参数的启用或者关闭需要重启集群。