postgres數據庫壞塊修復

轉自:http://www.redgres.com/web/node/17 

 由於磁盤壞道或者是內存問題等硬件上的原因,有時候會導致數據庫的數據文件的一些數據塊的損壞,使得某些表不能正常訪問,本文談一下PostgreSQL數據塊損壞時候,表數據的恢復方法

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

# select * from test ;

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

這個錯誤是說數據所在的目錄下面base子目錄,oid�?4780的數據庫,表的文件id�?4781的表(即上述例子的test)的第一�?注意是從0頁開�?數據塊的頭出現了錯誤,所以數據庫不能訪問�?/p>

 

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

 

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

 

重要:在做下面的操作前,先把數據庫的數據文件的目錄先備份!!!!�?/p>

 

方法1 利用參數zero_damaged_pages

 

PostgreSQL提供了一個隱藏參數zero_damaged_pages�?當這個參數爲true的時候,會忽略所有數據有損壞的頁面。設置的方法爲:打開postgresql.conf文件,在文件的添加一個參數zero_damaged_pages = true, 重起PostgreSQL�?/p>

 

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

# select count(*) from test ;

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

 count

-------

   760

(1 row)

 

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

 

這種方法不會對物理文件作修改,只是把內存上,損壞頁面的緩存變�?�?/p>

 

方法2 手動清除損壞的頁�?/p>

 

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

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

 

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

 

清除完後,查詢表即可正常訪問�?/p>

 

# select count(*) from test ;

count

-------

   760

(1 row)

 

 

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章