为什么FPW是以牺牲(性能、存储空间、稳定性)换取的可靠性?
文章开始前推荐2个学习环境:
1、欢迎使用镜像快速体验PostgreSQL/DuckDB强大功能:《最好的PostgreSQL学习镜像》
2、欢迎使用云起实验室: 《免费体验PolarDB开源数据库》
3、PolarDB开源数据库内核、应用等学习图谱: https://www.aliyun.com/database/openpolardb/activity
为什么FPW是以牺牲(性能、存储空间、稳定性)换取的可靠性?
https://www.bilibili.com/video/BV1jR4y137Yo/
背景知识:
数据库的数据文件以block的形式来进行组织. 每个block的大小可选2k,4k,8k,16k,32k.
修改数据块的内容时, 先将数据块从存储读到shared buffer里, 修改后再由bgwriter或checkpointer调度从shared buffer内存写入到磁盘.
磁盘通常以扇区(512字节)进行组织, 一次IO的最小单位也通常小于block size, 那么当block正在从内存写入到磁盘时, 如果发生这几个事情, 可能出现坏块:
断电, block的一部分可能是新的状态, 另一部分可能是老的状态.
在线备份, 拷贝文件, 同样拷贝到的block的一部分可能是新的状态, 另一部分可能是老的状态.
磁盘快照, 快照内的block的一部分可能是新的状态, 另一部分可能是老的状态.
如果出现坏块, 将导致数据不一致或损坏. 怎么检测出这种块错误?
block checksum.
怎么解决坏块问题?
FPW, full page write. 在将block从内存写出到磁盘前, 必须确保这个block的完整页面的内容已经写入到wal日志中(对于同一个block, 每次checkpoint后只有这个block第一次发生变化时需要写一次full page到wal中).
如果开启了FPW, 即使出现了datablock 坏块, 也能从wal的full page中恢复到一致的状态.
fpw 牺牲了什么?
性能:
当更新或删除时, 每次checkpoint后都要写入更多的wal(fpw), 即使每个page只更新1条记录, 第一次也需要写1个完整的page. 导致性能损耗. 如果checkpoint频繁, 这个性能损耗会更加明显.
当datablock被vacuum进行垃圾回收或freeze时, 每次checkpoint后第一次修改的page需要写完整的page到wal(即使每个page只更新少量内容). 导致性能损耗. 如果checkpoint频繁, 这个性能损耗会更加明显.
存储空间:
消耗更多的WAL存储空间: 包括wal目录, 归档文件, standby的wal文件.
同时消耗更多网络带宽(primary-standby的网络带宽)
稳定性(指SQL RT)
对于高并发频繁update, delete的场景, 每次checkpoint时, SQL RT 抖动会比较明显, 原因: 此时WAL日志暴增(full page write), wal的排他锁、IO写延迟等可能更加集中. 影响性能.
PolarDB:
PolarDB 计算存储分离架构版本. 采用PolarStore, 支持大于block size的原子写.
因此不需要开启fpw.
PolarDB 三节点分支, 同样允许关闭fpw. 关闭fpw后采用从standby节点读取datafile来解决FPW的问题. 详见:
《PolarDB PostgreSQL 开源训练营回放》
本期问题1:
请问PolarDB PG三节点版本在关闭fpw后进行数据恢复时, 从哪里读取checksum有错误的data block?
a. WAL里面的full page datablock
b. 当前实例的数据文件
c. standby节点的数据文件
d. 归档的WAL日志文件
答案:
c
解释:
PolarDB PG三节点版本可以关闭fpw, 关闭fpw后, 会从standby节点的数据文件读取需要的data block.
本期问题2:
请问PolarDB PG共享存储版本为什么可以关闭fpw而不会导致data block出现partial write的坏块?
a. 存储支持超过data blocksize的原子写.
b. 开启了 block checksum
c. 在其他地方写了一份FULL PAGE
d. 从standby 节点取得full page
答案:
a
解释:
PolarDB 计算存储分离版本采用PolarStore存储或者其他支持超过data blocksize的原子写的SAN存储或者分布式块存储时, 存储的原子操作和PFS对齐后, 可以关闭fpw, 而不会产生data block的partial write.
本期问题3:
请问开启full page write有哪些负面影响?
a. recovery时需要从wal中读取full page导致恢复性能下降.
b. 高并发的更新、删除小事务, 在遇到检查点时很大概率会发生较为明显的SQL RT抖动
c. 在发生vacuum freeze时, 由于开启fpw可能产生大量的full page, 导致standby延迟变大
d. 如果检查点频率很高, 开启fpw会导致写更多的wal日志, 从而导致归档的拷贝压力、存储空间变大
答案:
bcd
解释:
fpw不影响恢复性能, 反而可能对恢复性能有帮助, 因为不需要从datafile中获得block(减少了离散IO).
本期问题4:
请问以下哪些文件系统可以关闭full page write而不会导致数据文件不一致的问题?
a. zfs
b. ext4
c. xfs
d. 支持cow(copy on write)功能的文件系统
答案:
ad
解释:
文件系统支持copy on write, 并且在打开cow后, 实际上与数据库FPW的功能类似, 因此可以关闭数据库的fpw.
欢迎关注我的github (https://github.com/digoal/blog) , 学习数据库不迷路.
近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:
文章中的参考文档请点击阅读原文获得.