什么是數據損壞
存儲故障通常是指讀取或寫入數據的存儲介質出現的物理上的故障,存儲故障通常會帶來數據損壞甚至數據丟失的風險。
checksum
PostgreSQL在9.3版本開始,引入了checksum,使用checksum可以檢驗數據塊的損壞
頁面有效性檢驗發生在離開共享緩沖區和進入共享緩沖區之前。
checksum寫入
當將頁面從緩沖區緩存寫入到操作系統頁面緩存(OS Cache)時,就會計算checksum值並寫入數據頁中。
checksum校驗
每次讀取該塊時,checksum值就會重新計算,並與所存儲的checksum值進行比較。這可以檢驗數據是否損壞。
checksum使用示例
1、先檢查下當前數據庫是否開啟checksum,0代表關閉,1代表打開
pg_controldata -D /usr/local/pgsql/data |grep checksum
2、創建表並查詢表的物理存儲位置
create table tab1(a int primary key ,b text);
insert into tab1 values (1,'hello postgres'); select pg_relation_filepath('tab1');
3、關閉數據庫,啟用checksum
pg_ctl -D /usr/local/pgsql/data stop
pg_checksums -D /usr/local/pgsql/data --enable --progress
pg_ctl -D /usr/local/pgsql/data start
4、使用dd命令模擬數據文件損壞
dd bs=8192 count=1 seek=1 of=/usr/local/pgsql/data/base/12723/16384 if=/usr/local/pgsql/data/base/12723/16384
5、此時再去查詢表,可以看到查詢報錯:
select * from tab1 ;
6、停掉數據庫,使用checksum檢查數據頁的錯誤
7、將16進制的D7B1轉換為10進制,得到55,217,這和錯誤是匹配的。
8、沒有開啟checksum下的數據文件損壞,可能導致查詢到錯誤的數據
現在關掉checksum
pg_ctl -D /usr/local/pgsql/data stop
pg_checksums -D /usr/local/pgsql/data --disable --progress
9、啟動數據庫后去查詢數據,可以發現查詢出的數據是錯誤的
數據頁損壞如何處理
可以通過設置zero_damaged_pages參數去清理損壞的頁面,然后獲取剩下的結果。
show zero_damaged_pages;
set zero_damaged_pages=on;
select * from tab1 ;
我們看一下這個參數的含義:
zero_damaged_pages
( boolean
)
檢測到損壞的頁頭通常會導致PostgreSQL報告錯誤,中止當前事務。設置zero_damaged_pages
為 on 會導致系統報告警告,將內存中損壞的頁面清零,然后繼續處理。這種行為會破壞數據,即損壞頁面上的所有行。但是,它確實允許您克服錯誤並從表中可能存在的任何未損壞的頁面中檢索行。如果由於硬件或軟件錯誤而發生損壞,它對於恢復數據很有用。在您放棄從表的損壞頁恢復數據的希望之前,您通常不應設置此選項。清零頁不會被強制寫入磁盤,因此建議在再次關閉此參數之前重新創建表或索引。默認設置為off
,並且只能由超級用戶更改。
以上,說明這參數的使用需要謹慎。
開啟checksum帶來的影響
On an average if you enable checksum the performance cost would be more than 2% and for inserts, the average difference was 6%. For selects, that jumps to 19%.
平均而言,如果啟用校驗和,性能成本將超過 2%,對於insert,平均差異為 6%。對於select,這會跳到 19%。
完整的性能影響計算准則可以參見:https://www.endpoint.com/blog/2015/12/postgres-checksum-performance-impact/
參考文檔:https://postgreshelp.com/postgresql-checksum/