聊聊PG的FULL_PAGE_WRITES

那么Oracle是如何解决块断裂的问题呢?有很多网上的帖子说Oracle比较牛,是通过十分复杂的算法来解决块断裂的问题的,也有人说是oracle的REDO/UNDO可以保证不出现块断裂。
实际上这些说法是不正确的。
Oracle确实简单粗暴的在RDBMS层面不考虑块断裂保护的事情,把这些事情交给存储系统去做,目前的ORACLE ASM里面已经支持原子写,通过ASM的原子写机制来确保块不断裂,不过ASM原子写的保证机制是否有效,还有很多争论,在使用ASM的时候出现数据库坏块也是常有的事情,因此Oracle ASM是否真正能解决块断裂问题,从哪个版本开始解决了块断裂的问题尚未得到官方的正面认证,待老白有时间的时候去研究一下。
Oracle解决块断裂的最简单方法是支持块恢复(block recovery),当块断裂发生时,通过block recovery直接从备份介质中恢复某一块来解决这个问题。
你都花了几百万买Oracle了,那么把备份搞上是标配,否则遇到块断裂就算你倒霉。PG的FULL_PAGE_WRITES是当某个数据块在CHECKPOINT的时候被写回数据文件后,再次被修改的时候,第一次,PG会把这个块的整块写入WAL日志,而不只是写入变更的矢量。这一的话,哪怕操作系统或者存储故障,都可以在WAL中找到这个数据块的一个一致性的副本,再从这个副本开始前滚WAL日志,实现数据恢复。FULL_PAGE_WRITES确实可以保障数据库的安全,不过这种保障是有代价的,那就是大量的WAL的产生。我在一个测试环境下做过一个测试,关闭FULL_PAGE_WRITES后,在一个NVME SSD,WAL和CHECKPOINT相关参数已经优化过的环境下,TPMC指标提升了10%以上。如果在IO性能较差的环境中,可能这个提升还会更高。有些测试表明,关闭FULL_PAGE_WRITES的性能提升可能高达30%以上。但是为了数据库的安全,在绝大多数环境中还是建议不要关闭这个功能。
正是因为PG数据库的这个机制会导致CHECKPOINT后WAL的量会剧增,因此PG总是尽可能延缓CHECKPOINT的产生,延缓把脏块写回OS。
因此CHECKPOINT的优化就十分关键,如果这方面没有优化好,那么PG的写入性能就会很差。

另外在一些情况下,如果你的OS或者文件系统支持原子写入,比如ZFS文件系统,它能够确保一个块被以原子的方式一次性写入(ZFS也是存在类似WAL的日志的),那么PG就可以关闭FULL_PAGE_WRITES了。有国外的网友测试过,使用ZFS,关闭FULL_PAGE_WRITES,PG的QPS提高了超过20%。实际上目前LINUX的EXT4文件系统也是支持日志的,如果在EXT4打开日志的情况下(mount参数里加入data=journal),我们也可以关闭FULL_PAGE_WRITES,从而获得性能的提升。

不过任何情况下,多一层安全保护总不是坏事,因此当我们的PG数据库系统还没有需要挖掘每一分性能潜力,必须通过关闭FULL_PAGE_WRITES来解决问题的时候,我们还是暂时先不要关闭这个选项。首先考虑通过优化CHECKPOINT相关的配置,把WAL放到更快的盘上来优化性能。另外要注意的是FULL_PAGE_WRITES对于数据块的修改操作影响很大,而对于只读操作的影响是有限的,在考虑是不是要关闭FULL_PAGE_WRITES的时候,也需要充分评估风险与获得的好处之间的收益率。另外在分析FULL_PAGE_WRITES产生了多大的影响的时候,通过pg_stat_bgwriter性能视图去分析backend写脏块的比例是十分有效的,如果这个比例太高,那么很可能你的CHECKPOINT有点太慢了。不同的应用负载,CHECKPOINT的调整策略是不同的,需要根据你的系统的实际情况去做调整,而不要用僵化的思路去调整。

聊聊PG的FULL_PAGE_WRITES》来自互联网,仅为收藏学习,如侵权请联系删除。本文URL:http://www.hashtobe.com/277.html