1. 程式人生 > >Oracle的日誌挖掘恢復資料

Oracle的日誌挖掘恢復資料

  oracle日誌挖掘是一種十分強大的資料恢復技術,只要你保障你的歸檔日誌和重做日誌是完整的,那麼就可以將你的資料恢復到任何時刻。簡單敘述一下日誌挖掘的基本原理,然後進行一個簡單的小實驗。

  日誌挖掘時基於redo日誌和歸檔日誌的基礎之上來進行日誌載入並進行恢復,挖掘,挖掘,挖的就是你的redo日誌和歸檔日誌,當資料庫執行過程中,你的所有資料更改操作會被記錄在redo日誌中,而oracle redo日誌記錄著undo日誌,所以可以使用記錄在redo日誌中undo日誌來對你所做的操作進行回退。我們只需要確定你所做的操作被記錄在哪個時間範圍內,然後通過時間或者scn號將這個時間範圍內的操作載入到 v$logmnr_contents這個檢視中,然後找到對應的undo記錄,執行undo記錄的sql語句,就可以將你的資料恢復至更改前的狀態。

  可能說的有點難理解,我們來做一個簡單的實驗。

  首先確定資料庫執行在歸檔模式下,否則日誌一旦被覆蓋,那肯定是沒辦法恢復的,當然,可以通過其他方式,如閃回方式等,但是今天僅僅只針對日誌挖掘來進行描述。

1、archive log list --檢視系統是否執行在歸檔模式

我的庫是在歸檔模式,如果沒有歸檔,在mount下開啟歸檔。

2、alter database add supplemental log data; --啟動最小日誌,這一步是為了日誌更加詳細,完整。

3、更新一條資料,將new york 更改為test。

4、這個資料更新的時間範圍大約是在17點10分之20分。

5、將這個時間段的日誌載入到v$logmnr_contents這個檢視中。載入方式有很多種,我們使用線上字典自動載入,這種方式支援以時間範圍方式載入日誌。呼叫相應的儲存過程,除了時間其他的都是固定引數。

6、到此,我們將17點10分到17點20分的redo日誌載入到v$logmnr_contents檢視中,檢視v$logmnr_contents檢視的undo記錄,。

註解:seg_name 是更改的表名,seg_owner是表所屬的使用者,sql_redo是redo日誌記錄的sql資訊,剛才是做了一個update操作,所以使用like查詢有update欄位的欄位。過濾條件可以自己定義,只要能確定是哪條資料就可以。查出來的sql_undo 就是你的回退sql 用這條sql就可以將資料恢復到更改前的狀態。

7、執行undo欄位中的sql。

至此,資料成功恢復,但是在生產環境中需要恢復的資料往往有很多,可能幾千甚至幾萬條,可以寫一個迴圈來對資料進行插入,如下。

註解:利用for迴圈中的隱式遊標儲存sql_undo欄位中的資料,然後一次執行需要sql進行資料恢復