Oracle LogMiner(日誌挖掘器)是分析 Redo Log(重做日誌)與 Archived Log(歸檔日誌)的核心工具。它能將二進制日誌還原為可讀的 SQL 語句,是 DBA 處理以下場景的「時光機」:
DELETE/TRUNCATE/DROPSQL_UNDO 反向語句恢復資料| 元件 | 用途 | 關鍵程序/視圖 |
|---|---|---|
DBMS_LOGMNR_D | 建立/匯出資料字典 | BUILD、DBMS_LOGMNR_D.BUILD |
DBMS_LOGMNR | 核心分析引擎 | ADD_LOGFILE、START_LOGMNR、END_LOGMNR |
| 字典來源 | 線上目錄 / 扁平檔 / Redo Log 內嵌 | DICT_FROM_ONLINE_CATALOG、DICT_FROM_REDO_LOGS |
| 結果視圖 | 挖掘輸出 | V$LOGMNR_CONTENTS(核心)、V$LOGMNR_LOGS、V$LOGMNR_PARAMETERS |
-- 僅授予必要權限給分析用戶(如 SCOTT)
GRANT EXECUTE ON DBMS_LOGMNR TO scott;
GRANT SELECT ON V_$LOGMNR_CONTENTS TO scott;
GRANT SELECT ON V_$LOGMNR_LOGS TO scott;
GRANT SELECT ON V_$LOGMNR_PARAMETERS TO scott;
GRANT SELECT ON V_$DATABASE TO scoot; -- 查詢 DBID/RESETLOGS
CONN / AS SYSDBA
ALTER SYSTEM ARCHIVE LOG CURRENT; -- 切換日誌,確保有完整歸檔
CREATE TABLE mytesttab AS SELECT * FROM scott.dept; -- 4 筆測試資料
INSERT INTO mytesttab VALUES (80, 'IT', 'WA');
INSERT INTO mytesttab VALUES (90, 'MGR', 'YR');
COMMIT;
DELETE FROM mytesttab; -- 誤刪全部 6 筆
COMMIT;
ALTER SYSTEM ARCHIVE LOG CURRENT; -- 再次切換,封存刪除操作
-- 查詢近期歸檔日誌路徑
SELECT name FROM v$archived_log
WHERE first_time > SYSDATE - 1/24 -- 最近 1 小時
ORDER BY first_time;
-- 假設目標檔案為:
-- D:/oracle/Flash_recovery_area/MYOracle/ARCHIVELOG/2007_08_11/O1_MF_1_4_3CVHLKJM_.ARC
-- 1. 新增日誌檔案到分析清單
EXEC DBMS_LOGMNR.ADD_LOGFILE(
LOGFILENAME => 'D:/oracle/Flash_recovery_area/MYOracle/ARCHIVELOG/2007_08_11/O1_MF_1_4_3CVHLKJM_.ARC',
OPTIONS => DBMS_LOGMNR.NEW
);
-- 2. 啟動分析,使用線上資料字典(無需預建字典檔)
EXEC DBMS_LOGMNR.START_LOGMNR(
OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG
);
V$LOGMNR_CONTENTS4.1 查看操作類型與時間線
SELECT scn, timestamp, seg_owner, operation
FROM v$logmnr_contents
WHERE seg_name = 'MYTESTTAB';
輸出示例:
| SCN | TIMESTAMP | SEG_OWNER | OPERATION |
|---|---|---|---|
| 5483840 | 11-8月-07 | SYS | DDL |
| 5483863 | 11-8月-07 | SYS | INSERT |
| 5483874 | 11-8月-07 | SYS | INSERT |
| 5483885 | 11-8月-07 | SYS | DELETE |
| 5483886 | 11-8月-07 | SYS | DELETE |
4.2 關鍵欄位:SQL_REDO(正向 SQL)與 SQL_UNDO(反向 SQL)
-- 正向重做語句(可用於重演操作)
SELECT sql_redo FROM v$logmnr_contents WHERE seg_name = 'MYTESTTAB';
-- 反向撤銷語句(黃金資料:直接拿來執行即可恢復資料!)
SELECT sql_undo FROM v$logmnr_contents WHERE seg_name = 'MYTESTTAB';
SQL_UNDO 輸出範例(可直接執行恢復):
INSERT INTO "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") VALUES ('10','ACCOUNTING','NEW YORK');
INSERT INTO "SYS"."MYTESTTAB"("DEPTNO","DNAME","LOC") VALUES ('20','RESEARCH','DALLAS');
...
DELETE FROM "SYS"."MYTESTTAB" WHERE "DEPTNO"='80' AND "DNAME"='IT' AND "LOC"='WA' AND ROWID=...;
EXEC DBMS_LOGMNR.END_LOGMNR;
-- 連續添加多個歸檔日誌
EXEC DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '...arc1', OPTIONS => DBMS_LOGMNR.NEW);
EXEC DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '...arc2', OPTIONS => DBMS_LOGMNR.ADDFILE);
EXEC DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '...arc3', OPTIONS => DBMS_LOGMNR.ADDFILE);
EXEC DBMS_LOGMNR.START_LOGMNR(
OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG
+ DBMS_LOGMNR.START_SCN(123456)
+ DBMS_LOGMNR.END_SCN(123999)
-- 或使用時間
-- START_TIME => TO_DATE('2024-01-15 10:00','YYYY-MM-DD HH24:MI')
-- END_TIME => TO_DATE('2024-01-15 11:00','YYYY-MM-DD HH24:MI')
);
-- 僅看 SCOTT 用戶的 EMP 表刪除操作
SELECT sql_undo
FROM v$logmnr_contents
WHERE seg_owner = 'SCOTT'
AND seg_name = 'EMP'
AND operation = 'DELETE';
| 字典來源 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
DICT_FROM_ONLINE_CATALOG | 當前資料庫結構未變 | 零準備、即時可用 | 無法分析結構已變更的歷史日誌 |
DICT_FROM_REDO_LOGS | 需分析過去結構不同的日誌 | 自包含、可攜帶離線分析 | 需預先將字典寫入 Redo Log |
扁平檔字典 (DBMS_LOGMNR_D.BUILD) | 離線分析、跨庫分析 | 獨立於目標資料庫 | 維護成本高、易過期 |
ARCHIVELOG)START_TIME/END_TIME 縮小範圍SQL_UNDO 產生恢復腳本LogMiner 是 Oracle DBA 工具箱中的「核武器級」工具。掌握 ADD_LOGFILE → START_LOGMNR → 查詢 V$LOGMNR_CONTENTS → END_LOGMNR 核心流程,配合 SQL_UNDO 反向語句,能在 Flashback 失效時成為最後防線。建議每位 DBA 定期演練「誤刪資料 → LogMiner 恢復」全流程,將 RTO(恢復時間目標)壓縮至分鐘級。