一、概述
在PGSQL数据库中,默认的页面大小为8KB,但是磁盘buffer的大小为4KB,扇区大小为512B。这就导致在操作系统的角度看数据库的写操作,其实并不是一种原子操作。如果操作系统发生了系统级别的故障,此时正好操作系统刷入了一个8KB页面的前半部分4KB,那么后半部分将缺失或失去了一致性。PGSQL自带的一致性校验方法可以检测到这种不一致性,但是无法解决这种不一致性。因此PGSQL采用了一种叫做全页写(Full Page Write)的机制来避免这种操作
二、全页写
为了解决上面的问题,MySQL采用的是双写机制,即保留备份页面,遇到页撕裂的情况时用备份页面覆盖写。但在PGSQL中,选择将整个数据页保存在WAL日志中。以checkpoint作为标志,当一个页面在checkpoint后被第一次修改时,会触发全页写机制。全页写在配置项里是可选的,参数为full_page_writes,默认为ON。在PITR期间,强制开启。在数据库备份操作期间,也会开启这个选项,用于防止出现页撕裂问题。
具体来说,页面会在其中记录最近一次操作的LSN,数据库的控制文件中也会记录数据库最近一次checkpoint时对应的LSN。这样就可以依此判断是否需要触发全页写。