浦東數據恢復:PG數據庫的故障修復
瀏覽量: 次 發布日期:2023-09-11 09:48:21
上點硬菜:聊聊PG數據庫的故障修復
IT運維的恐懼主要來自于對運維對象的內在原理的認知不足,而數據庫運維的底線在于數據的保全。90年代末的時候,我們對Oracle數據庫的理解并不深入,而且那時候企業在數據庫備份等方面的投入也不足。正是那時候我第一次遇到了Oracle數據庫服務器故障的情況。當時客戶的操作系統徹底壞掉了,重裝操作系統并重新安裝了Oracle數據庫軟件,把磁盤陣列上的Oracle掛載起來后,數據庫實例無法啟動。在客戶必須盡快恢復數據庫服務的需求下,我一邊翻閱手頭僅有的幾本技術資料,一邊猜測其原理,一邊嘗試打開數據庫。我也打電話咨詢了很多Oracle方面的專家,當時有不少人都認為這樣情況,沒有做數據庫備份的情況下,這套數據庫恢復無望。而我則覺得所有的數據庫文件都沒有損壞,數據庫是一定能恢復的。經過近兩天的努力,數據庫終于恢復了。幸虧當時是周末,只影響了周六幾個小時的業務,也算是萬幸了。從那以后,我才感受到理解Oracle數據庫內部原理的重要性,開始研究起來,這也是我后來寫作《DBA的思想天空》的一個起點。隨著對Oracle內部原理的理解的不斷深入,我們對于Oracle的運維也越加自信。很多以前不敢關閉數據庫進行系統維護的客戶也都明白了數據庫重啟并不是一件高風險的事情。甚至90年代面試DBA的時候經??嫉臑槭裁床荒躶hutdown abort關閉數據庫也成了一道錯題。這種運維能力的提升也讓運維工作變得更科學起來了。而Oracle數據庫無論出現何種問題,只要數據文件還在,我們總是能有辦法解決其存在的問題。剛剛開始使用PG數據庫的時候,我也在考慮,如果PG數據庫也出現了類似的問題,比如數據庫處于不一致狀態,操作系統故障,丟失某些文件等,我們是不是也能像運維Oracle數據庫一樣來解決這些問題呢?今天我就給大家分享一些這樣的干貨。實際上各種數據庫丟失文件、數據文件不一致,存在某些損壞,要解決這些問題,實際上涉及的都是REDO和UNDO的問題,解決REDO的不一致問題,可以讓數據庫在損失部分數據(甚至不損失數據)的情況下強行啟動,從而減少部分損失。解決UNDO的問題,可以確保在丟失部分數據的一致性的情況下強行打開數據庫,從而讓數據損失減少到最少。無論是Oracle、DB2還是今天我們討論的PG,通過重置日志文件(REDO或者WAL)都可以強行打開一個不一致的數據庫。和Oracle一樣,不管PG數據庫出現什么樣的問題,只要數據文件都還在,修復數據庫的可能性是很大的。只要找到一個和本數據庫版本一致的運行環境,后續一步步的修復數據庫,打開數據庫實例是大概率的。在修復數據庫的時候,盡可能使用完全一致的數據庫軟件版本,從而避免一些不必要的麻煩。PG數據庫提供了一個重置WAL文件的工具pg_resetwal/pg_resetxlog(10以前版本),這個工具對于丟失一些PG的文件導致PG數據庫無法啟動可以進行強制修復。大家要注意的是,使用這個工具修復數據庫是不得已而為之的做法,不過這個工具在一些非專業運維人員手里被當成了一個日常使用的工具,用來做各種各樣的事情,包括誤刪數據恢復等。這實際上是十分危險的,一些常規性的恢復操作最好還是用常規手段來進行,這種操作只是作為沒辦法情況下的操作手段。使用這種手段修復的數據庫,也有可能因為修復使用的參數存在不準確而導致數據庫能正常啟動,但是數據庫本身存在問題的情況。另外就是不同版本的工具的參數上可能會有略微的差異,使用前一定要認真閱讀相關版本的文檔。如果僅僅是數據庫存在一些不一致,或者丟失了部分WAL文件,那么我們只需要通過這個工具生成一個最新的WAL文件就可以強制打開數據庫了。我們來看一個例子,比如一數據庫實例突然宕機了,而且WAL文件丟失了。因為這個WAL里可能包含了活躍的記錄,因此數據庫啟動的時候會出現錯誤??聪旅娴睦樱喝缓驪ostmaster被異常終止。刪除所有的WAL文件,刪掉共享內存段。然后重啟數據庫。可以看到,因為WAL文件都丟失了此時數據庫是無法啟動。這種時候可以通過pg_resetwal工具去修復這個錯誤。使用pg_resetwal $PGDATA就可以完成修復,如果數據庫存在不一致情況,需要使用-f參數強制修復??梢钥吹叫迯秃髷祿靻恿?。不過剛才CHECKPOINT之后寫入的一條數據丟失了。上面的例子是最簡單的,我們再來看一個稍微復雜一些的例子。如果pg_control文件也丟失了,那么除了簡單的reset wal之外,我們還需要首先恢復pg_control文件。pg_control文件位于$PGDATA/global目錄下,是PG數據庫中十分重要的記錄各種重要數據庫基本信息的文件,和Oracle的controlfile十分類似。如果這個文件損壞或者丟失,PG數據庫就無法打開了。今天我們以這個文件順壞的場景,來學習一下如何使用這個工具來修復PG數據庫。要想用pg_resetwal來修復數據庫,重修生成丟失或者損壞的pg_control文件,需要確定幾個參數。上海數據恢復
揚州數據恢復
1) -l, --next-wal-file=WALFILE,這個參數設置下一個新的WAL文件的最小值,這個值可以從$PGDATA/pg_wal目錄下去看最后一個WAL 文件,這個文件的id+1就可以了。這個文件+1,-l 000000010000099B000000352)-x, --next-transaction-id=XID,這個參數設置pg_control中的下一個XID的值,這個值可以從pg_xact目錄下的文件中查詢到。最后一個是0392,那么下一個XID就是0393,然后乘以 1048576 (0x100000),實際上后面直接加5個0就行了。注意,這個值是16進制的。-x 0x0393000003)-m, --multixact-ids=MXID1,MXID2,這個參數包含兩個部分,MXID1和MXID2,都可以從$PGDATA/pg_multixact/offsets目錄下獲得。MXID1的值,首先找到最大值,+1,再乘以 65536 (0x10000,相當于后面加4個0)作為這個參數的前半部分。找到最小的值,后面加4個0,作為MXID2的值。這個例子中,-m 0x00570000, 0x00080000
4)-O, --multixact-offset=OFFSET,這個參數可以從$PGDATA/pg_multixact/members目錄下獲得。找到最大值,+1,乘以 52352 (0xCC80),這個需要進行計算,沒有簡單的加0的方法。-O 0x00BAED00
根據上面所述的參數的情況,這個例子要修復pg_control文件的命令為:pg_resetwal -O 0x00BAED00 -m 0x00570000,0x00080000 -x 0x039300000 -l 000000010000099B00000037 $PGDATA
準備好命令后,首先要做幾個準備動作。如果你的數據庫是異常宕機的,那么$PGDATA/postmaster.pid文件可能還沒刪掉,需要手工刪除。然后到$PGDATA/global目錄下,生成一個空的pg_control文件(touch pg_control)。否則執行命令會報錯。準備好之后,就可以執行命令了。上面的命令執行過程中,所有的參數都已經被校驗了,而且是可接受的。不過因為需要強制執行,所以需要加上-f參數。執行結束后,就可以嘗試重啟啟動數據庫了。數據庫能夠成功啟動了。要注意的是,命令執行成功,并不一定說明pg_control文件就正確修復了。如果你輸入的參數有問題,那么數據庫還是無法啟動的。如果你的數據庫成功啟動了,那么校驗一下你所需要的書是否都是正確的。要說明的是這個命令的各種參數的確定要十分謹慎,一旦錯誤,數據庫打開后,一些不一致帶來的問題就比較麻煩了。在實際的生產環境中做這件事,你一定要首先完整備份書后再操作,否則你沒有犯錯誤的機會。實際上pg_resetwal工具還有很多十分重要的作用,今天時間有限,我們就不多說了,以后找時間再給大家分享。