1. 程式人生 > >[Logmnr]使用logminer找回被誤刪的資料

[Logmnr]使用logminer找回被誤刪的資料

LogMiner日誌挖掘技術在有些時候可以被比作是命懸一線的救命稻草,比方說誤刪除資料(如delete執行不當),可以通過LogMiner挖掘日誌檔案將這些資料補插回來

使用LogMiner預覽:

  • LogMiner的原理就是找出日誌檔案(redo file),所對應的undo.如你新增1W行資料,在redo裡以insert形式體現,對應的undo即為delete
  • LogMiner所有操作要在單個會話裡執行
  • LogMiner是挖掘線上日誌或歸檔日誌,因此最好要知道誤操作的具體(精確更好)時間,這樣能夠儘可能少的挖日誌,恢復時間將更短
  • LogMiner挖掘之後的資料將儲存在V$LOGMNR_CONTENTS.但需要注意一點,它的資料是每次查詢時候才去讀取的,因此涉及的日誌檔案多的時候,查詢將非常慢.因此建議將檢視內容用CATS儲存起來,便於後來查詢
  • 源庫的日誌檔案可以在源庫本地做挖掘,也可以在其他機器做挖掘,但有版本和系統要求: 目標作業系統要採用同一位元組編碼順序(ENDIAN_FORMAT);資料庫版本大於或等於源資料庫版本,且字符集相同
  • 所有計劃納入挖掘的日誌,需要來自同一資料庫,且基於同一個RESETLOGS SCN
  • 既然LogMiner可以分析日誌,那麼就可以用於統計哪些表被增刪改查最多,可以更深入地瞭解自身的應用和資料
  • LogMiner可以基於time/SCN進行挖掘,精確
  • 使用挖掘技術的使用者需要被授權角色或許可權: SELECT ANY TRANSACTION , EXECUTE_CATALOG_ROLE
  • 如果表被誤truncate或誤drop,LogMiner恢復不了,可以通過ODU/DUL/PRM/AUL工具來恢復

概念

  • 源庫:生成歸檔日誌和線上日誌的庫
  • 目標庫:執行LogMiner進行日誌分析的庫
  • 字典:英文名為CATALOG,用於把日誌中的內部資訊翻譯成實際的表名、列名等有價值資訊
  • 源庫與目標庫可以是同一個,也可以是不同的。如果不同,要求目標庫資料庫版本高於或等於源庫;字符集要相同;作業系統、硬體平臺要相同
一、準備工作
  • 源庫需要開啟歸檔模式
  • 源庫需要開啟最小補充日誌
--開啟最小補充日誌功能
SQL> alter database add supplemental log data;
Database altered

--查詢最小補充日誌是否開啟
SQL> select supplemental_log_data_min from v$database;
SUPPLEMENTAL_LOG_DATA_MIN
-------------------------
YES
客觀的說追加日誌不是必需,如果不啟用追加日誌SESSION_INFO等很多有用的資訊解析後都沒有,顯示會為“UNKNOWN”。

二、 LogMiner字典模式 1、使用線上字典
這種方式是Oracle推薦的,適用於在源庫做LogMiner,也是最易用的一種方式。
execute dbms_logmnr.start_logmnr(options => dbms_logmnr.dict_from_online_catalog);  
2、把字典放到線上日誌檔案
適用於源庫與目標庫不同這樣的方式

execute dbms_logmnr_d.build(options=> dbms_logmnr_d.store_in_redo_logs);  
3、把字典生成OS上的一個檔案
這樣的方式是要是為了相容9i及之前的版本,實際使用中這樣的方式需要在源庫設定UTL_FILE_DIR引數,不方便。

execute dbms_logmnr_d.build('logmnr_dict.ora','/home/oracle/',dbms_logmnr_d.store_in_flat_file);
Oracle已不推薦這樣方式。

三、舉例演示

1、重做日誌連線

2、歸檔日誌連線

四、一些有用的選項

1、COMMITTED_DATA_ONLY
顧名思義就是隻顯示已經提交了的,那些正在進行中的及Oracle內部操作都忽略掉了

2、DDL_DICT_TRACKING
適用於線上日誌存放LogMiner字典的情況,當表發生了新增欄位等情況,字典自動更新。

execute dbms_logmnr.start_logmnr(options =>dbms_logmnr.ddl_dict_tracking + dbms_logmnr.dict_from_redo_logs);  

3、 NO_SQL_DELIMITER
去掉SQL_REDO及SQL_UNDO中SQL語句最後的分號,以CURSOR方式迴圈執行解析出的SQL會很方便和快捷。

execute dbms_logmnr.start_logmnr(options =>dbms_logmnr.no_sql_delimiter + dbms_logmnr.dict_from_redo_logs);

4、NO_ROWID_IN_STMT

在SQL_REDO和SQL_UNDO列語句中去掉ROWID。舉例:

execute dbms_logmnr.start_logmnr(options=>dbms_logmnr.no_rowid_in_stmt + dbms_logmnr.dict_from_redo_logs);

五、有用檢視

V$LOGMNR_LOGS 新增的需解析的日誌列表
V$LOGMNR_CONTENTS 解析結果