天天看點

非正常方法,輕松應對Oracle資料庫危急異常

作者:唐小丹(浙江移動資料庫管理者)

           周  凱(上海新炬資料庫工程師)

相信很多oracle dba在職業生涯中或多或少都遇到過這樣的情況:資料檔案被誤删了,存儲壞了無法識别資料檔案,最糟糕的是,竟然rman備份也是壞的…… 遇到問題淩亂慌張是沒用的,而貿然動手也是非常危險的,當遇到緊急問題,最重要的就是冷靜分析,臨危不亂。

下面我通過幾個實戰案例,給大家介紹幾例資料檔案異常可采用的非正常恢複方法。

一、資料檔案被删除的恢複

實驗場景:由于維護人員的誤操作,導緻資料庫部分資料檔案被删除,資料庫報錯。

>>>>故障模拟

10點59分,誤操作删除檔案

非正常方法,輕松應對Oracle資料庫危急異常

11點20分資料庫alert日志顯示出現ora-01116等錯誤,根據背景日志顯示此時ts_test01.dbf檔案已經無法正常打開。

非正常方法,輕松應對Oracle資料庫危急異常

但是資料庫沒有是以關閉,還處于read write狀态。

非正常方法,輕松應對Oracle資料庫危急異常

>>>>問題分析

資料檔案被誤删,資料庫仍然處于open狀态。對于此問題可以通過linux系統的“檔案描述符”找回丢失的資料檔案。在linux系統中一切皆可以看成是檔案,檔案描述符(file descriptor)是核心為了高效管理已被打開的檔案所建立的索引,所有執行i/o操作的系統調用都通過檔案描述符。檔案描述符打開的檔案句柄以及i-node的關系如圖:

非正常方法,輕松應對Oracle資料庫危急異常

在linux 系統中,資料檔案被删除後,其檔案句柄還被相關資料庫程序所打開使用,可以通過該句柄資訊直接複制将其恢複。需要注意的是,在此期間資料庫不能關閉。否則相關句柄将被釋放,檔案就無法找回。

>>>>恢複步驟

嘗試通過oracle dbwr程序找到被誤删除的檔案句柄

非正常方法,輕松應對Oracle資料庫危急異常

目前的oracle dbwr程序的spid是3293 可以通過該程序找到丢失的ts_test01.dbf 檔案句柄

非正常方法,輕松應對Oracle資料庫危急異常

含一些數字命名的目錄,它們是程序目錄,其下的fd子目錄包含程序相關的所有的檔案描述符。子本例中oracle的dbwr 程序的fd目錄下正有已經被删除的ts_test01.dbf檔案的描述符(注:檔案描述符為25,目前的狀态是deleted)

非正常方法,輕松應對Oracle資料庫危急異常

通過copy的方式恢複已删除的資料檔案,并設定正确的屬組權限。

非正常方法,輕松應對Oracle資料庫危急異常
非正常方法,輕松應對Oracle資料庫危急異常

通過将offline 相關表空間并重置檔案路徑的方式完成檔案重定向。

非正常方法,輕松應對Oracle資料庫危急異常

由于前期資料檔案無法open的問題,部分已更改的資料無法寫入資料檔案,導緻datafile header 上的checkpoint#和controlfile檔案的checkpoint_change#不一緻,需要對資料檔案進行媒體恢複。

非正常方法,輕松應對Oracle資料庫危急異常

進行媒體恢複之後,表空間可以正常online,故障處理也算完成。

>>>>總結感悟

作為系統維護人員rm,mv均屬于高危操作,在執行之前一定要反複思考,确定影響,做到“甯停3分,不搶1秒”。當遇到資料庫問題時,應維持故障現狀,在沒有清楚的了解問題原因以及解決方案之前,草率的行動将使問題複雜化,造成不可估量的損失。對于此案例,如果貿然的關閉資料庫,隻能使用rman備份進行恢複,如果備份失效,資料丢失将不可避免。總之做到,臨危不亂!三思而行!

二、使用bbed跳過歸檔檔案的完全恢複

實驗場景:存儲損壞導緻部分資料檔案損壞,需要使用備份進行還原,在資料庫恢複階段發現缺失部分歸檔,導緻資料庫無法恢複,正常啟動。

>>>>實驗環境準備

使用rman 為資料庫做一個全備

非正常方法,輕松應對Oracle資料庫危急異常

對test表執行insert操作,每三次insert後執行一次switch logfile,保證生成的34,35,36三個歸檔各包含3條insert的記錄檔。

非正常方法,輕松應對Oracle資料庫危急異常
非正常方法,輕松應對Oracle資料庫危急異常

通過abort方式停庫後,删除ts_test01.dbf 檔案模拟存儲故障。

非正常方法,輕松應對Oracle資料庫危急異常

人為删除sequence 35的歸檔日志。至此,故障已經重制。

非正常方法,輕松應對Oracle資料庫危急異常

當再次使用startup指令啟動時,資料庫在mount之後由于無法識别到datafile 6(ts_test01.dbf),最終隻能停留在mount階段。

非正常方法,輕松應對Oracle資料庫危急異常

通過rman 的方式進行資料檔案還原。在媒體恢複階段rman報錯:no backup of archived log for thread 1 with sequence 35 and startingscn of…….。正是因為缺失了35号歸檔導緻還原無法完成(35号歸檔已經被人為删除)。

歸檔日志按時間順序記錄着資料庫上的各類操作(包括insert,delete,update,create 等等)。歸檔的丢失意味着部分操作的缺失,oracle将無法繼續後續的歸檔檔案的恢複。

在此情況下使用正常手段顯然無法正常open資料庫。需要通過bbed跳過缺失的歸檔使其繼續完成媒體恢複。

通過rman的crosscheck archivelog all指令校驗歸檔日志發現,缺少35号歸檔。

非正常方法,輕松應對Oracle資料庫危急異常

跳過缺失的歸檔需要将6号檔案的scn向前推進至少大于等于36号歸檔的first change#1243371

非正常方法,輕松應對Oracle資料庫危急異常

資料檔案的scn被記錄在檔案1号block偏移量484位元組開始的四個位元組中。目前6号檔案的scn經過大小端轉換之後十進制的數值為1243327(dump的原值為bff81200經大小端轉換後的十六進制為0012f8bf)。該值正好是35号歸檔的first change#

非正常方法,輕松應對Oracle資料庫危急異常

使用bbed更改資料檔案頭的scn号,使其變為1243381(注意更改的scn需要大于36号歸檔的first change#,在這次實驗中使用36号歸檔的first change#10作為新的scn号,經過十六進制以及大小端轉換後資料為f5f812), 并使用sum apply 指令重新計算校驗和。

非正常方法,輕松應對Oracle資料庫危急異常

要想跳過歸檔還需要資料檔案頭塊的rba。它由seq#、log block#、偏移量(固定為16)組成,決定了資料檔案從哪個歸檔日志的哪個位置開始應用歸檔。rba位于資料檔案頭塊偏移量500處開始連續的12個位元組(如圖從23開始到0000ffff結束,前4個位元組是日志的序列号,中間4個位元組是日志塊号,最後4個位元組是偏移量)。

非正常方法,輕松應對Oracle資料庫危急異常

将rba修改為接下去的歸檔日志.log block#.offset#(這次試驗rba被修改為24000000.02000000.10000000即36.2.16)

非正常方法,輕松應對Oracle資料庫危急異常

再次執行資料檔案6的媒體恢複後資料庫可以正常打開。由于跳過了部分日志,免不了存在資料丢失或者不一緻的問題。對于采用此方法恢複的資料庫建議在合适的時候停機重建。

非正常方法,輕松應對Oracle資料庫危急異常

備份作為保障資料安全的最後一道防線,備份檔案的有效性應該得到充分的驗證。校驗發現備份集異常,丢失等問題時,應該及時發起新的資料庫備份。

oracle資料庫好比一個龐大而精密的機器,關鍵檔案好比機器中的傳動齒輪,任何的缺失都會導緻整個系統的停滞崩潰。作為一個合格的dba,我們既要會用機器,也要會修機器,更要膽大心細,臨危不亂,為資料庫的持久穩定運作保駕續航。

<b></b>

<b>本文來自雲栖社群合作夥伴"dbaplus",原文釋出時間:2016-04-08</b>