標籤:需要 source class -- 根據 http 輸入 結構 方式
原文:http://www.talkwithtrend.com/Article/216335前言
資料庫最嚴重的故障莫過於資料庫損壞。資料庫壞頁是資料庫損壞的一種,如果資料庫中有資料頁出現損壞,在沒有訪問到壞頁時,資料庫可以正常提供服務,當使用到壞頁所在的表,有可能導致資料庫的崩潰。
導致資料庫出現壞頁的可能性有很多,比如突然的掉電、主機down機,或者儲存、磁碟的故障等等。
當資料庫出現壞頁時,首先使用作業系統命令判斷是否出現硬體故障,修複硬體故障後,可以嘗試使用"db2 restart db dbname"命令讓資料庫執行崩潰恢複,這種方法有可能恢複資料庫的正常。如果不適用與上述方法,那麼最好的辦法就是從備份恢複資料庫。
如果無法從備份恢複,那麼在資料庫可以串連的情況下,可以採用db2look匯出表結構和export匯出資料的方法來重建資料庫。當然對於損壞的表,只能使用db2dart工具離線匯出這些表的資料,處於坏頁上的資料庫極有可能丟失了。
如果資料庫無法串連了,只能使用db2dart離線匯出整個資料庫的資料。匯出資料之後,剩下的就是重建庫並且匯入資料了。
本文記錄了一次生產環境中資料庫頁頭的損壞的資料庫壞頁故障,經過一波三折的修複過程,最終恢複了絕大部分資料,恢複了資料庫的正常運行。
環境介紹
作業系統版本 AIX 6100-07-04-1216
資料庫版本 DB2 v9.7.0.7
該資料庫比較大,大概2.2T,出現壞頁的表資料量也比較大,大概30G。
一、問題發現
業務同事查詢XXX資料庫的某個報表查詢,出現如下報錯:
二、初步分析
查看該報錯的解釋:
db2 "? sql1655c"
查看資料庫的nfy日誌:
more db2npsh.nfy
2017-08-07-14.14.44.308129 Instance:db2npsh Node:000
PID:12517626(db2agent (NPSH) 0) TID:25497 Appid:*LOCAL.db2npsh.170807055005
buffer pool services sqlbReadPage Probe:1199 Database:NPSH
ADM6006E DB2 encountered an error while reading page "114482656" from table
space "3" for object "1859" (located at offset "114482688" of container "/dev/rlvts_npsh_d8").
2017-08-07-14.14.55.313501+480 E1900111A837 LEVEL: Critical
PID : 12517626 TID : 11548 PROC : db2sysc 0
INSTANCE: db2npsh NODE : 000
EDUID : 11548 EDUNAME: db2pfchr (NPSH) 0
FUNCTION: DB2 UDB, buffer pool services, sqlbLogReadAttemptFailure, probe:10
MESSAGE : ADM14001C An unexpected and critical error has occurred: "BadPage".
The instance may have been shutdown as a result. "Automatic" FODC
(First Occurrence Data Capture) has been invoked and diagnostic
information has been recorded in directory
"/db2/dump/npsh/FODC_BadPage_2017-08-07-10.09.10.302693_0000/".
Please look in this directory for detailed evidence about what
happened and contact IBM support if necessary to diagnose the
problem.
同時,也發現dump目錄下產生FODC_BadPage的檔案。
三、進一步分析
嘗試定位出現壞頁的表:
根據db2npsh.nfy 日誌中的資訊table space "3" for object "1859",查詢如下:
db2 "select tabname,status from syscat.datapartitions where tbspaceid =3 and tableid=1859"
沒有輸出,懷疑是分區表的某個分區壞了,查詢如下:
db2 "select tabname,DATAPARTITIONNAME from syscat.datapartitions where tbspaceid=3 and PARTITIONOBJECTID=1859"
輸出如下:
NXXXXTRFH PART201707
可以判斷是這個分區出現壞頁。
查詢該表的狀態,正常:
db2 "select tabname,status,tbspaceid,tableid from syscat.tables where tabname=‘NXXXXTRFH‘"
從該表查詢資料,正常:
db2 "select * from dbnpsh. NXXXXTRFH fetch first 10 rows only"
所以說資料庫的壞頁比較複雜,有時候壞頁導致整個表故障,而本次,表面上查看起來,表資料一切正常。當跑報表訪問到特定的頁時才報出故障。
嘗試通過load from cursor的方法把壞頁的表分區的資料匯出來,和報表查詢語句報同樣的錯誤:
嘗試通過export匯出資料:
db2 "export to /db2/archlog/npsh/NXXXXTRFH_PART201707.ixf of ixf select * from db2npsh.NXXXXTRFH_PART201707"
匯出hang住,兩個小時後,匯出400多萬資料,出現同樣的報錯,而且資料量明顯不對
收集所有的日誌資訊,發送給IBM800協助進行分析問題。
db2support . -d npsh -c -s
經分析,IBM二線確認出現資料庫壞頁,建議使用db2dart匯出表資料:
四、資料修複步驟
下面是資料找回的過程:
卸載表分區
由於該表大小達到30G,嘗試將表分區卸載下來單獨匯出:
db2 alter table dbnpsh.NXXXXTRFH detach partition PART201707 into NXXXXTRFH_PART201707
卸載成功
db2dart準備工作
執行db2dart之前,需要準備兩點:
1、斷開所有資料連線
db2 force applicaitons all
2、擴容dump目錄至能夠放下整個分區的資料
db2dart匯出資料
db2dart匯出資料
開始執行db2dart匯出資料:
db2dart npsh /DDEL
然後輸入:1859,3,0,999999
(四個參數的意義分別為:對象id,資料表空間id,起始頁號,匯出總頁數)
IBM建議匯出總頁數設定為999999頁
db2dart操作執行2小時,發現匯出的頁數已經達到999998,懷疑匯出的頁數超過設定的999999上限。看來IBM給的建議也不是完全準確。
將頁數改為99999999,重新執行db2dart匯出(需要先刪除之前置出的dart目錄):
db2dart npsh /DDEL
然後輸入:1859,3,0,99999999
曆時三個小時後,匯出成功,總共匯出1100000多頁。
匯出檔案名稱預設TS3T1859.DEL。
將dart出來的資料放入暫存資料表
建立暫存資料表NXXXXTRFH_PART20170702,注意指定的資料表空間要和NXXXXTRFH主表保持一致。
將dart出的資料匯入到暫存資料表:
db2 -v "LOAD FROM TS3T1859.DEL of del INSERT INTO DB2NPSH.NXXXXTRFH_PART20170702 NONRECOVERABLE"
匯入出現“欄位類型不符”的報錯,經過排查,是由於該表包含DBCLOB大欄位,這種欄位dart命令無法匯出。查詢原表,發現該欄位為空白,慶幸不會丟失大欄位資料,但是由於資料檔案和表結構不匹配,匯入成了一個問題。
有兩種方案解決這個問題:
第一,編輯資料檔案,定位到大欄位那一列,插入一個逗號,即插入一列空列。
第二,建立不包含大欄位列的表,匯入資料後再添加大欄位。
建立NXXXXTRFH_PART20170703不包含dbclob列,匯入資料:
db2 -v "LOAD FROM TS3T1859.DEL of del INSERT INTO DB2NPSH.NXXXXTRFH_PART20170703 NONRECOVERABLE"
Number of rows read = 23771029
Number of rows skipped = 0
Number of rows loaded = 23770943
Number of rows rejected = 86
Number of rows deleted = 0
Number of rows committed = 23771029
添加列
db2 "alter table db2npsh.NXXXXTRFH_PART20170703 add column URL DBCLOB(2048) LOGGED NOT COMPACT"
執行成功。將暫存資料表掛載到主表上
將暫存資料表掛載到主表上:
db2 "alter table dbnpsh.NXXXXTRFH attach partition PART201707 starting (‘20170701‘) ending (‘20170731‘) from DB2NPSH.NXXXXTRFH_PART20170703"
掛載失敗:
SQL20408N Table "DB2NPSH.NXXXXTRFH_PART20170703" cannot be attached to
table "DBNPSH.NXXXXTRFH" because column "PAYEENM" of the source table and
its associated column "URL" of the target table do not match. Reason code = "8". SQLSTATE=428GE
經分析,原因是暫存資料表的列順序和主表不一致。
解決方案:
將03暫存資料表的資料通過指定列的方式insert到02暫存資料表:
db2 -v "INSERT INTO DB2NPSH.NXXXXTRFH_PART20170702 SELECT MSGID,INSTGBKID,MSGCD,SEQNB,INSTGDRCTPTY,BIZTYP,BIZKIND,SYSCD,REGTIME,TRANCHNLTYP,CREDTTM,INSTDDRCTPTY,INSTDPTY,RMK ,PAYERNM,PAYERDPSTBKNM,DBTRDPSHDL,PAYERTELE,PAYERACCTNO,PAYERACCTYP,PWD ,PYMTAGRMT,AUTHPYMTBIZKIND,PTCID,URL,PAYEENM,CDTRDPSHDL,PAYEEDPSTBKID,PAYEEDPSTBKNM,PAYEEACCTNO,ACCTLTD,AGRINEFFCTVDT,AGREFFCTVDT,SNGLTXAMTLMT,ORIGMSGID,CSTMRNB,CDTRCSTMRID,DLTTLCNT,DAYAMTUPPERLMT,CURCD,MSLTTLCNT,MTHAMTUPPERLMT,MAGETYP,ACQFEE,CLRDATE,BIZPRCSCD,BIZRJCTCD,BIZRETSTS,RJCTRESN,BIZSTS,CTRLIND,BIZBIGTYP,ADDINFO1,ADDINFO2,ADDINFO3,ADDINFO4,ADDTBNM,SIGNATURE,TRADEFLAG,RPLIRACCT,RPLIRNM,RPLIRDPSNM,RPLIRDPSHDL,RPLIRACCTTP,QRISTACCT,QRISTNM,QRISTPTYNM,QRISTPTYHDL FROM DB2NPSH.NXXXXTRFH_PART20170703"
將02暫存資料表掛載到主表:
db2 "alter table dbnpsh.NXXXXTRFH attach partition PART201707 starting (‘20170701‘) ending (‘20170731‘) from DB2NPSH.NXXXXTRFH_PART20170702"
掛載成功
SQL3601W The statement caused one or more tables to automatically be placed
in the Set Integrity Pending state. SQLSTATE=01586
一致性檢查
進行一致性檢查:
db2 set integrity for dbnpsh.NXXXXTRFH immediate checked
執行大概十分鐘,成功。
DB20000I The SQL command completed successfully.
資料量確認
查詢201707分區的資料量:
db2 "select count(*) from DBNPSH.NXXXXTRFH where CLRDATE>=‘20170701‘ and CLRDATE<=‘20170731‘"
匯入資料總條數:23770943
原資料條數:
db2 "select count(*) from DB2NPSH.NXXXXTRFH_PART201707"
原資料總條數:23771388
損壞的資料條數:23771388-23770943=445條
至此,資料恢複完成,找回23770943條資料,損壞445條。
(轉)Db2資料庫一次生產故障詳細記錄---資料庫壞頁