小伙伴有使用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。