pg 檔案塊損壞的修復措施。

babyyellow發表於2012-06-13

抄來了的
比較忙,沒有時間測試,先放這裡了

pg 沒有檔案塊級別的資料庫恢復操作。





由於磁碟壞道或者是記憶體問題等硬體上的原因,有時候會導致資料庫的資料檔案的一些資料塊的損壞,使得某些表不能正常訪問,本文談一下PostgreSQL資料塊損壞時候,表資料的恢復方法。

PostgreSQL採用一個表存放在一個或者多個物理檔案,所以資料塊的損壞一般只會影響到一個表,使得該表的資料不能查詢或者是備份,下面是一個常見的異常的例子:

# select * from test ;

ERROR: invalid page header in block 1 of relation base/34780/34781

這個錯誤是說資料所在的目錄下面base子目錄,oid為34780的資料庫,表的檔案id為34781的表(即上述例子的test)的第一頁(注意是從0頁開始)資料塊的頭出現了錯誤,所以資料庫不能訪問。



資料塊的損壞的情形比較複雜,所以如何恢復,或者是能恢復到什麼情形不能一概而論。最好的情況是丟失一個資料塊裡面的所有記錄(也有可能只丟失某些記錄, 但是方法比較複雜),最壞也有可能整個表丟失。PostgreSQL沒有提供像Oracle那樣的檔案恢復或者是塊修復的功能,但也有一些方法可以修復 表,這裡簡單討論一下一個資料塊損壞的情況下,如何恢復。



最簡單的方法是,用備份恢復!如果你有做備份和日誌歸檔,則出現問題以後,恢復到最新即可。如果沒有備份,則請參考下面的方法。



重要:在做下面的操作前,先把資料庫的資料檔案的目錄先備份!!!!!



方法1 利用引數zero_damaged_pages



PostgreSQL提供了一個隱藏引數zero_damaged_pages, 當這個引數為true的時候,會忽略所有資料有損壞的頁面。設定的方法為:開啟postgresql.conf檔案,在檔案的新增一個引數 zero_damaged_pages = true, 重起PostgreSQL。



設定完後,當訪問表的時候,會提示說已經忽略損壞的頁面:

# select count(*) from test ;

WARNING: invalid page header in block 1 of relation base/34780/34781; zeroing out page

count

-------

760

(1 row)



該表原有1000條記錄,由於一個頁面損壞,丟失了240條記錄。表可以訪問以後,可以把表dump下來,或者是select到另外一張臨時表,然後把原來的表刪除掉重建。當然如果有其他外部約束的話,相關的表和索引也要處理,這裡不詳細討論。



這種方法不會對物理檔案作修改,只是把記憶體上,損壞頁面的快取變為0。



方法2 手動清除損壞的頁面



在某些情形下,zero_damaged_pages可能不一定有些,這時可以嘗試手動把壞的頁面清除。

根據錯誤提示 ERROR: invalid page header in block 1 of relation base/34780/34781 我們可以找到相應的檔案, 檔案的路徑為: 資料目錄/base/34780/34781,只要用工具手動把上面提示的壞塊清除即可。在Linux下面可以用dd工具把相應的頁面清除:



$dd if=/dev/zero f=/home/postgres/data/base/34780/42995 bs=8192 seek=1 count=1 conv=notrunc



清除完後,查詢表即可正常訪問。



# select count(*) from test ;

count

-------

760

(1 row)





上面簡單討論了一下資料塊損壞的表的恢復方法。由於這些方法都是有一定的侷限性,而且丟失資料的資料量也不是完全確定,所以平時一定要做好備份工作。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/133735/viewspace-732673/,如需轉載,請註明出處,否則將追究法律責任。

相關文章