Oracle LogMiner 使用

Oracle官方文档Using LogMiner to Analyze Redo Log Files[2]中,对该功能有详细的介绍,包括了LogMiner的配置与使用、数据过滤、补充日志(Supplemental Logging)、使用示例等。

Oracle 何时引入的LogMiner?

自 1999 年发布 Oracle 8i 的时候,正式引入 LogMiner 功能(参考:Redo Log Analysis Using LogMiner[1])。该功能支持以SQL的形式分析redo中的数据,最初考虑的应用场景,主要还是偏于故障恢复、异常诊断、审计等,但是该功能的潜力很大,现在已经逐步成为Oracle CDC的主流方案之一。

目前已经有很多的集成/同步工具都使用LogMiner进行变化数据获取,虽然,目前官方依旧不推荐这么做,文档中的原文如下:“Note:LogMiner is intended for use as a debugging tool, to extract information from the redo logs to solve problems. It is not intended to be used for any third party replication of data in a production environment.”

根据经验来看,LogMiner用于数据集成并没有什么太大的问题。

打开补充日志

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

查看归档日志

SQL> SELECT name FROM v$archived_log ORDER BY FIRST_TIME DESC FETCH FIRST 3 ROWS ONLY;

NAME
----------------------------------------------------------------------------------------------------
/u03/app/oracle/fast_recovery_area/ORCLCDB/archivelog/2025_04_24/o1_mf_1_761_n0mbccbd_.arc
/u03/app/oracle/fast_recovery_area/ORCLCDB/archivelog/2025_04_24/o1_mf_1_760_n0mbcc62_.arc
/u03/app/oracle/fast_recovery_area/ORCLCDB/archivelog/2025_04_24/o1_mf_1_759_n0m6tdfp_.arc

添加需要解析的日志文件

BEGIN
  DBMS_LOGMNR.ADD_LOGFILE(
    LOGFILENAME => '/PATH_TO_YOUR_ARCHIVE/o1_mf_1_761_n0mbccbd_.arc',
    OPTIONS => DBMS_LOGMNR.NEW
  );
END;
/

例如,实际的SQL可能是如下的样子:

BEGIN
  DBMS_LOGMNR.ADD_LOGFILE(
    LOGFILENAME => '/u03/app/oracle/fast_recovery_area/ORCLCDB/archivelog/2025_04_24/o1_mf_1_955_n0mwc01v_.arc',
    OPTIONS => DBMS_LOGMNR.NEW
  );
END;
/

o1_mf_1_955_n0mwc01v_.arc
o1_mf_1_909_n0mv4sc3_.arc
o1_mf_1_908_n0mv4ohs_.arc

启动LogMiner

启动时,可以带不同的参数以指定LogMiner不同的行为。

使用在线数据字典启动
EXECUTE DBMS_LOGMNR.START_LOGMNR( -
   OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);
使用日志中的数据字典启动
EXECUTE DBMS_LOGMNR_D.BUILD( -
    OPTIONS => DBMS_LOGMNR_D.STORE_IN_REDO_LOGS);

获取LogMiner中的变更数据

获取变更数据
SELECT 
  SCN,
  TIMESTAMP,
  OPERATION,
  SQL_REDO,
  SQL_UNDO,
  SEG_OWNER,
  TABLE_NAME,
  USERNAME
FROM 
  V$LOGMNR_CONTENTS
WHERE 
    OPERATION IN ('INSERT', 'UPDATE', 'DELETE')
--  AND SEG_OWNER = 'TEST_USER'
    AND (TABLE_NAME = 'T2' OR TABLE_NAME = 't2')
ORDER BY TIMESTAMP DESC
FETCH FIRST 3 ROWS ONLY;

退出 LogMiner

EXECUTE DBMS_LOGMNR.END_LOGMNR();

解析未归档的 Redo 日志

除了解析归档之外,LogMiner 可以直接解析当前正在使用的 redo 文件。先根据小节“获取当前正在使用的redo文件”中的SQL获取当前正在使用的 redo 文件,然后在添加日志文件时,像上述添加归档一样添加即可。

BEGIN
  DBMS_LOGMNR.ADD_LOGFILE(
    LOGFILENAME => '/u04/app/oracle/redo/redo003.log',
    OPTIONS => DBMS_LOGMNR.NEW
  );
END;
/

使用上述(小结“获取变更数据”)的SQL可以获得如下的输出:

       SCN TIMESTAMP OPERATION	  SQL_REDO
---------- --------- ------------ ---------------------------------------------
   3175619 24-APR-25 INSERT       insert into "SYS"."T2"("ID") values ('31');
   3175846 24-APR-25 INSERT       insert into "SYS"."T2"("ID") values ('32');

一些常见的 SQL

获取归档日志

获取最新的ARCHIVE LOG的列表,以及对应的SCN号范围:

SELECT 
  FIRST_CHANGE#,
  TO_CHAR(FIRST_TIME, 'YYYY-MM-DD HH24:MI:SS'),
  NEXT_CHANGE# ,
  TO_CHAR(NEXT_TIME, 'YYYY-MM-DD HH24:MI:SS'),
  NAME 
FROM  
  V$ARCHIVED_LOG 
ORDER BY NEXT_CHANGE# DESC 
FETCH FIRST 3 ROWS ONLY;
强制切换归档日志文件
ALTER SYSTEM SWITCH LOGFILE;
获取当前正在使用的redo文件
SELECT A.GROUP#,A.MEMBER, B.STATUS
FROM   V$LOGFILE A
JOIN   V$LOG B ON A.GROUP# = B.GROUP#
WHERE  B.STATUS = 'CURRENT'; 

参考

Leave a Reply

Your email address will not be published. Required fields are marked *