一、概述
在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。這樣就可以依此判斷是否需要觸發全頁寫。