plsql查看表空间_最佳实践—PG数据库系统表空间重建
Global 默認是PG的系統表空間,存儲的是共享系統字典表還有控制文件相關信息,此表空間下的文件是整個數據庫系統訪問控制的核心,一旦損壞數據庫訪問將會受限,尤其是控制文件受損將會導致系統的不可用,本文通過實際的現場global下文件受損導致數據庫不可用案例,來講述如何重構系統表空間以及控制文件來恢復數據庫,從而通過邏輯備份快速導出數據,對以后postgresql 的global下的文件損壞而導致的數據庫問題可以嘗試使用此方法。
1.?問題的提出
接到客戶現場反饋說業務應用連接數據庫異常,提示global目錄下對象存在無效的頁,通過遠程過去查看日志發現確實pg數據庫的核心表空間下的對象出問題,詳細的跟現場了解下情況,現場反饋說服務器硬盤壞了(服務器有raid 磁盤冗余保護),很難理解怎么會影響上層的業務應用,原來是客戶要定期的從服務器上要拷貝生產業務報告(電網內有隔離),當時U盤不可用服務器廠商讓客戶重啟服務器試試,誰知道起不來了,據說服務器廠商讓客戶又做了拔掉電源等系列匪夷所思的操作后系統能夠正常登陸了,但是此時數據庫就掛了,從整體的描述來看初步判斷是服務器的raid卡出問題了導致系統登錄問題以及識別不到U盤。報錯信息:
2.?解決思路
根據以上的信息聯想到是否可以通過跳過無效的頁來解決問題,仔細分析后發現此問題跟我們實際當中碰到的數據頁損壞還是有區別的,因為數據頁損壞我們跳過數據不訪問便是,但是系統表空間下對象信息是一點也不能被忽視,也想過是否可以向oracle那樣重建系統表空間呢,可是并找到pg相關重建系統表空間的方法,那怎么辦呢?比較慘的事情遠遠沒有結束,檢查備份發現近一年的備份都是無效備份,看來通過備份的方式是沒戲了,當時感覺天是黑黑的!
無效備份文件:
好消息是數據庫可以正常登陸:
2.1.?如何解決問題
1、是否可以嘗試別的方式恢復global:有個想法既然global下存儲的是共享系統字典表,那么我們是不是就可以通過初始化一個庫來重新生成新的global呢?感覺可行,但是這里面有個問題就是需要重建控制文件,ok有思路總比一頭霧水強,說干就干.
1):通過物理拷貝的方式備份數據庫副本來進行驗證操作
2):我通過initdb 初始化一個實例
3):拷貝原備份副本里面的global文件到global_bak
4):拷貝新生成的global表空間目錄到原備份副本中
5):嘗試重建控制文件
6):嘗試拉起數據庫
[highgo@localhost highgo]$ ll
總用量 16
drwx------. 21 highgo highgo 4096 12月 25 09:25 9.4? ? ? ? --原數據庫數據文件
drwx------. 20 highgo highgo 4096 12月 24 18:06 9.4_bak? ? --備份數據庫副本
drwx------. 18 highgo highgo 4096 12月 24 17:27 9.5? ? ? ? --初始化數據庫數據文件
[highgo@localhost 9.4_bak]$ ll
總用量 152
drwx------. 7 highgo highgo? 4096 12月 24 17:45 base
drwx------. 2 highgo highgo? 4096 12月 25 09:26 global? ? ? ? --初始化拷貝新global文件? ?
drwx------. 2 highgo highgo? 4096 12月 24 18:33 global_bak? ? --原表空間備份副本
drwxr-x---. 2 highgo highgo? 4096 12月 24 17:59 hgdb_log
drwx------. 2 highgo highgo? 4096 12月 24 18:46 pg_clog
2.2.?計算控制文件信息
1、查看pg_xlog
按照早期9.2的版本pg_resetxlog –l 參數需要-l timelineid,fileid,seg三個參數現場是9.4的版本只需要一個參數指定下一個事務日志號即可。2、查看pg_clog? ?
-x 參數來自pg_clog
查看pg_multixact
-O參數來自members
-m參數來自offsets
根據以上三個文件的內容我們計算的控制文件信息如下:
pg_resetxlog -l 00000001000000300000003D -x 0x002000000 -m 0x0003,0x0003 -O 0x0006 /opt/goldwind/pgdata/data/highgo/9.4_bak -f2.3.?異常情況
1、?準備好了一切按照我們的設想需要重啟庫來驗證下是否可行。
數據庫啟動正常,心理安心了不少。
Ok 數據庫可以正常訪問,心理的一塊石頭落地了!
2、?高興的有點早啊,因為發現數據庫是正常了,但是我們業務數據庫沒有想象中一樣出現,檢查發現數據肯定是存在的。
2.4.?恢復
1、?果然問題并沒有想的那么簡單,我們忽略了重要的信息,那就是字典表里面有部分對象存儲著初始化后新增對象的字典信息,既然這樣那么開始嘗試查看無效頁的對象:
由于對象沒有辦法確認那么我們只能嘗試著去規避這個對象了:
1) 清理此對象涉及的物理文件
2) 拷貝清理后的global所有對象到備份副本下
3) 嘗試再次重建控制文件
4) 嘗試啟動數據庫
5) 嘗試連接數據庫
6) 驗證成功后嘗試備份數據
3.?實踐情況
此文檔通過另一種方式恢復了數據庫的global表空間,幸運的是沒有碰到記錄系統對象的表,恢復之后在想如果碰到是類似pg_database數據丟失我們是不是也能通過此方法來處理呢,答案應可以,為什么呢,因為只要知道系統內的數據庫信息一樣可以人為的補全。
4.?效果評價
此現場沒有備份如果恢復不了面臨的就是20G生產業務數據的丟失,隨時不可估量,但是我們恢復了就說明此方法可行。
5.?推廣建議
建議極端情況下可以嘗試此方法,一般恢復后建議立即備份。6.?參考資料
無
?――完――
歡迎投稿
????????中國開源軟件推進聯盟PostgreSQL分會,歡迎大家積極投稿,向PGer分享自己的實踐經驗、心得體會,共建PG中國生態。
投稿郵箱:
partner@postgresqlchina.com
總結
以上是生活随笔為你收集整理的plsql查看表空间_最佳实践—PG数据库系统表空间重建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python去除视频马赛克_马赛克是否无
- 下一篇: 函数使用了堆栈的字节超过_单片机地址空间