63-Oracle LogMiner(23ai)-实操

发布于:2025-06-24 ⋅ 阅读:(15) ⋅ 点赞:(0)

小伙伴有使用OGG或是Kafka的么,日常抽取数据使用平滑么,数据抽取的准确和效率,从oracle logminer可以探索,oracle是如何这么丝滑控制日志抓取和导出分析的呢。LogMiner是Oracle生态中深度集成的日志分析引擎,其价值在事务级数据追踪与恢复场景无可替代。配合OGG/Kafka等工具时,需重点调整资源参数(如PROCESSES、PARALLELISM)以避免性能瓶颈,并在审计场景中充分启用补充日志以获取完整操作溯源信息。

一、LogMiner核心功能与技术原理

1. 核心功能​ 
历史操作追踪
  • 解析在线/归档重做日志中的DML(INSERT/UPDATE/DELETE)和DDL(CREATE/ALTER),输出操作时间、用户、SCN、事务ID等元数据。
数据恢复支持
  • 定位误操作(如误删数据)的精确SCN或时间点,生成反向SQL(SQL_UNDO)实现数据回滚。
审计与合规
  • 追踪敏感数据变更(如权限修改),满足安全审计要求(如记录操作用户、机器名需开启补充日志)。
性能与事务分析
  • ​通过事务分组(COMMITTED_DATA_ONLY选项)分析长事务、高负载操作,优化数据库性能。
2. 技术原理​ 
日志解析机制
  • 重做日志记录数据块变更向量(Change Vectors),LogMiner解析这些条目还原为SQL语句。
--依赖补充日志记录主键等额外信息:
-- 必备步骤 
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; 
数据字典映射
  • 将内部对象ID转换为可读名称,支持三种模式:
    • 在线字典​(DICT_FROM_ONLINE_CATALOG):实时解析当前对象。
    • 离线字典​(DICT_FROM_REDO_LOGS):字典导出至重做日志,用于历史日志分析。
    • 外部文件​(Flat File):独立存储的.dct文件。
事务一致性处理
  • 按SCN顺序缓存同一事务的所有DML,仅当解析到COMMIT时才输出,确保原子性。
动态视图输出
  • 结果存储在V$LOGMNR_CONTENTS,包含SQL_REDO(原始SQL)、SQL_UNDO(回滚SQL)、OPERATION等字段。

二、版本演进与关键特性​  

​版本

​新增特性

​技术意义​

​Oracle 8i

初始版本,支持基础日志解析

提供免费的内置日志分析能力

​Oracle 9i​

支持集群表、直接路径插入、DDL跟踪;离线字典;

事务分组(COMMITTED_DATA_ONLY)

增强复杂场景兼容性,支持离线审计

​Oracle 10g

非ASCII字符集支持、SQL解析优化

改善全球化兼容性与解析准确性

​Oracle 11g

性能优化(SGA内存管理)、XML格式支持、RAC增强

提升大规模日志处理效率

​Oracle 12c+​

容器数据库(CDB/PDB)支持、持续性能改进

适应云原生架构

三、与第三方产品的集成

1. Oracle GoldenGate (OGG)​​ 
  • 集成捕获模式​OGG的Integrated Capture模式依赖LogMiner解析重做日志,实现低延迟数据同步:
    • 注册LogMiner进程:OGG在数据库中创建CAPTURE进程,占用约15个数据库连接。
    • 参数调优:需调整PARALLELISM和MAX_SGA_SIZE以避免资源冲突(如ORA-01372进程不足)
  • 优势与限制
    • 支持压缩表、加密数据等复杂场景。
    • 高并发场景需扩大PROCESSES参数,否则可能触发连接数超限。
2. Kafka Connect Oracle​ 
  • 实时变更捕获​将LogMiner解析的变更流推送至Kafka

四、验证脚本和实践​ 

​1. 环境准备
-- 启用归档需要starup mount 开启 open(需重启)  
ALTER DATABASE ARCHIVELOG;
--切换日志
SYS@CDB$ROOT> alter system switch logfile;

System altered.

-- 检查归档模式与补充日志
SELECT log_mode, supplemental_log_data_min FROM v$database;
--补充日志信息不会独立生成新文件,而是作为附加信息嵌入到重做日志文件(Redo Log Files)中
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
--Database altered.
SYS@CDB$ROOT> SELECT MEMBER FROM V$LOGFILE;
MEMBER
______________________________________
/opt/oracle/oradata/FREE/redo03.log
/opt/oracle/oradata/FREE/redo02.log
/opt/oracle/oradata/FREE/redo01.log
--
SELECT log_mode, supplemental_log_data_min FROM v$database;
LOG_MODE      SUPPLEMENTAL_LOG_DATA_MIN
_____________ ____________________________
ARCHIVELOG    YES
方案 1:使用 Redo 日志字典
2. 离线字典配置(推荐历史日志分析)​
-- 导出字典到重做日志  
EXEC dbms_logmnr_d.build(OPTIONS => dbms_logmnr_d.STORE_IN_REDO_LOGS); 
-- 定位包含字典的归档日志  
SELECT name FROM v$archived_log WHERE dictionary_begin = 'YES';
--
PL/SQL procedure successfully completed.
SYS@CDB$ROOT> -- 定位包含字典的归档日志
SYS@CDB$ROOT> SELECT name FROM v$archived_log WHERE dictionary_begin = 'YES';

NAME
_________________________________________________________________________
/opt/oracle/DB_FRA/FREE/archivelog/2025_06_22/o1_mf_1_63_n5h8ds0o_.arc
/opt/oracle/DB_FRA/FREE/archivelog/2025_06_22/o1_mf_1_72_n5h9png6_.arc

3. 日志分析与结果提取 
--从 Oracle 10g 开始,UTL_FILE_DIR 参数不再推荐使用。官方建议改用 **CREATE DIRECTORY** 创建目录对象替代
--以 SYSDBA 身份执行
CREATE OR REPLACE DIRECTORY LOGMINER_DIR AS '/opt/oracle/logminer';
-- 2. 创建数据字典文件(需SYSDBA权限)
BEGIN
  DBMS_LOGMNR_D.BUILD(
    dictionary_filename => 'dict.ora',
    dictionary_location => 'LOGMINER_DIR'  -- 使用目录对象名而非路径
  );
END;
/
--3.将字典写入 Redo 日志​:
BEGIN
    DBMS_LOGMNR_D.BUILD(
        OPTIONS => DBMS_LOGMNR_D.STORE_IN_REDO_LOGS
    );
END;
/
-- 3.1查询当前日志文件
SELECT member 
FROM v$logfile 
WHERE group# = (SELECT group# FROM v$log WHERE status = 'CURRENT');
--
MEMBER
______________________________________
/opt/oracle/oradata/FREE/redo02.log
-- 检查2025-06-22的归档日志是否完整
SELECT name, sequence#, first_time, next_time, archived, status 
FROM v$archived_log 
WHERE first_time >= TO_DATE('2025-06-22 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
  AND next_time <= TO_DATE('2025-06-22 23:59:59', 'YYYY-MM-DD HH24:MI:SS')
ORDER BY sequence#;
--
NAME                                                                         SEQUENCE# FIRST_TIME    NEXT_TIME    ARCHIVED    STATUS
_________________________________________________________________________ ____________ _____________ ____________ ___________ _________

/opt/oracle/DB_FRA/FREE/archivelog/2025_06_22/o1_mf_1_69_n5h9k0j2_.arc              69 22-JUN-25     22-JUN-25    YES         A    
/opt/oracle/DB_FRA/FREE/archivelog/2025_06_22/o1_mf_1_70_n5h9pjxz_.arc              70 22-JUN-25     22-JUN-25    YES         A    
/opt/oracle/DB_FRA/FREE/archivelog/2025_06_22/o1_mf_1_71_n5h9pk4g_.arc              71 22-JUN-25     22-JUN-25    YES         A    
/opt/oracle/DB_FRA/FREE/archivelog/2025_06_22/o1_mf_1_72_n5h9png6_.arc              72 22-JUN-25     22-JUN-25    YES         A    
/opt/oracle/DB_FRA/FREE/archivelog/2025_06_22/o1_mf_1_73_n5h9pnv0_.arc              73 22-JUN-25     22-JUN-25    YES         A    

19 rows selected.

-- 4. 添加日志文件到分析列表(替换实际路径)
EXECUTE dbms_logmnr.add_logfile(
    logfilename => '/opt/oracle/oradata/FREE/redo02.log',
    options => dbms_logmnr.new
);
EXECUTE dbms_logmnr.add_logfile(
    logfilename => '/opt/oracle/DB_FRA/FREE/archivelog/2025_06_22/o1_mf_1_73_n5h9pnv0_.arc',
    options => dbms_logmnr.addfile
);

-- 5. 启动LogMiner分析(带时间范围)
EXECUTE dbms_logmnr.start_logmnr(
    dictfilename => '/u01/app/oracle/logminer/dict_2023.ora',
    starttime => to_date('2023-10-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss'),
    endtime   => to_date('2023-10-15 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
);

-- 6. 查询分析结果(必须在同一会话)
CREATE TABLE logmnr_results AS 
SELECT scn, timestamp, sql_redo, seg_owner, seg_name
FROM v$logmnr_contents
WHERE operation IN ('INSERT','UPDATE','DELETE');
--Table LOGMNR_RESULTS created.
-- 7. 结束分析释放内存
EXECUTE dbms_logmnr.end_logmnr;

-- 8. 查看分析结果
SELECT * FROM logmnr_results WHERE ROWNUM <= 10;
SELECT SCN,TIMESTAMP,SEG_NAME FROM logmnr_results;

       SCN TIMESTAMP    SEG_NAME
__________ ____________ ________________
   5724075 22-JUN-25    PDB_ARC_SKIP$
方案 2:推荐-使用在线目录​​

无需预生成字典,直接启动 LogMiner:

BEGIN
    DBMS_LOGMNR.START_LOGMNR(
        OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG
    );
END;
/
-- 1. 查询分析结果(必须在同一会话)
CREATE TABLE logmnr_results AS 
SELECT scn, timestamp, sql_redo, seg_owner, seg_name
FROM v$logmnr_contents
WHERE operation IN ('INSERT','UPDATE','DELETE');
--Table LOGMNR_RESULTS created.
-- 2. 结束分析释放内存
EXECUTE dbms_logmnr.end_logmnr;

-- 3. 查看分析结果
SELECT SCN,TIMESTAMP,SEG_NAME FROM logmnr_results;

       SCN TIMESTAMP    SEG_NAME
__________ ____________ ________________
   5724075 22-JUN-25    PDB_ARC_SKIP$
注意方案1​:
  • 仅能解析当前数据库对象结构的日志,若表结构发生过变更(如 DDL),则无法解析历史日志中的旧对象。
  • 适用于分析近期日志(表结构未变化
4. 关键注意事项​ 
资源与死循环风险
  • 避免直接CREATE TABLE log_analysis AS SELECT * FROM V$LOGMNR_CONTENTS; 动态视图会捕获自身操作,导致日志暴增和死循环。
平台与字符集限制
  • 日志文件必须与分析数据库字符集一致而且不支持跨平台(例如AIX→Windows)。
数据类型限制
  • 不支持索引组织表(IOT)、LOB、LONG及集合类型。

六、使用体验:

生产环境中建议优先使用 ​SCN 范围尽量不使用时间范围,避免因时区或时间精度问题导致日志遗漏。高可用环境结合 OGG 集成捕获模式(自动处理日志连续性)替代原生 LogMiner。


网站公告

今日签到

点亮在社区的每一天
去签到