文章目录

  • 一.前情:
  • 二.LogMiner介绍:
  • 三.logminer解析前提:
    • 3.1 开启归档模式
    • 3.2 启用补充日志
      • (1)补充日志分类
        • 1.1 最小补充日志:最基本的一种数据库级补充日志;
        • 1.2标识关键字段补充日志
      • (2)启用补充日志操作
      • (3)提交进行的更改:
    • 3.3 创建用户帐户
    • 3.4 提取日志挖掘字典(重做日志)
    • 3.5 挖掘数据
  • 四、清除归档日志
  • 五、代码层面抽取数据

一.前情:

  军工、医疗、 电力等多个领域需要进行数据同步,如oracle生产库数据实时同步到hive数仓中。针对这些场景,选择logminer作为解析日志工具,从归档日志中实时抽取增量数据。在解析归档的过程中遇到非常多的问题(如rac集群2线程归档后日志的实际路径与视图中的路径不一致、日志激增导致程序内存溢出等),把排查过程、问题解决方法、心得记录下来,也许有用。

  CDC的异步方式是非入侵方式(noninvasive)的实现,对于变化数据的捕获就不需要数据库加trigger。在CDC中变化的数据被保存在一个变化表中,使用者通过订阅的方式生成一个视图并且通过视图查询到变化的数据。

二.LogMiner介绍:

  Oracle LogMiner作为Oracle数据库组成部分,可分析出所有对于数据库的DML操作(INSERT、UPDATE、DELETE)语句以及DDL操作,另外可分析得到回滚SQL语句,适用于日志挖掘。详情可翻阅LogMiner的英文文档: Oracle Logminer

三.logminer解析前提:

3.1 开启归档模式

以具有 DBA 权限的用户身份登录数据库。
检查数据库日志记录模式:

select log_mode from v$database;

如返回 ARCHIVELOG,跳到下一步。

如返回 NOARCHIVELOG,继续执行:

关闭数据库:

shutdown immediate;

启动数据库:

startup mount;

配置启用归档并打开数据库:

alter database archivelog;
alter database open;

3.2 启用补充日志

(1)补充日志分类

1.1 最小补充日志:最基本的一种数据库级补充日志;

开启最小补充日志:

alter database add supplemental log data ;

查询是否启用最小补充日志:

select supplemental_log_data_min min from v$database ;

关闭最小补充日志:

alter database drop supplemental log data ;
1.2标识关键字段补充日志

  有四种类型:主键、唯一索引、外键、全体字段补充日志;标识关键字段补充日志必须建立在最小补充日志的基础上,当其被启用时,若最小补充日志尚未启用,则oracle会隐式开启最小补充日志,同样在没有关闭标识关键字段补充日志的时候,不能先关闭最小补充日志。

1.2.1.主键补充日志

  主键补充日志的作用是在update命令的重做记录中添加被修改行的主键字段的旧值,这是无条件式的补充日志,所谓无条件即无论主键字段本身是否被update命令修改,其旧值都会被记录。

  但是,不能保证每张表一定有主键。如果存在没有主键的表,则主键字段由长度最小的非空唯一索引字段代替。如果表结构中一个非空索引字段都没有,那么oracle将被修改行的所有字段(除了lob和long类型)的旧值都记录下来,这将导致重做记录的数据量暴涨,所以如果要启用主键补充日志,又为了维护lgwr和重做日志,每张表最好具有主键或至少一个非空唯一字段。

启用主键补充日志:

alter database add supplemental log data (primary key) columns ;

1.2.2.唯一索引补充日志

  只有当唯一字段被update时,才会记录该字段被修改前的值,因为唯一键索引是能够建立在多个字段上的

alter database add supplemental log data (unique) columns ;

1.2.3.外键补充日志

  外键补充日志和唯一索引补充日志一样同为有条件式的,只有当外键字段被update命令修改时,其修改前的旧值才会被记录

alter database add supplemental log data (foreign key) columns ;

1.2.4.全体字段补充日志

  全体字段补充日志和主键补充日志一样为无条件式的,无论哪个字段被update命令修改,所有字段(除了lob,long类型)的旧值都将被记录,其效果相当于启用了主键补充日志的前提下既没有主键也没有非空唯一索引字段的情况,这样几乎所有的表数据都搬到了重做日志中,不但存在当前的,历史数据也没有丢下。对恢复操作来说比较好,但是对于lgwr和磁盘空间就不是太好,一般很少启用这样的日志

 alter database add supplemental log data (all) columns;

(2)启用补充日志操作

验证是否为数据库启用补充日志:

SELECT supplemental_log_data_min, supplemental_log_data_pk,
supplemental_log_data_all FROM v$database;

  如果三列都返回 Yes 或 Implicit,则启用了主键补充日志和全体字段补充日志,直接进行下一步
  如果前两列返回 Yes 或 Implicit,则启用了主键补充日志,若满足需求,可进行下一步。
  如果没有满足条件,则根据选择执行下面命令:

启用主键补充日志的2种方式:
(1)以单个表为单位启用
先启用最小补充日志,再启用主键补充日志

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
ALTER TABLE <schema name>.<table name> ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY)COLUMNS;

(2)一次性对数据库所有表启用

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;

启用全体字段补充日志的2种方式:
(1)以单个表为单位启用

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
ALTER TABLE <schema name>.<table name> ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;

(2)一次性对数据库所有表启用

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;

(3)提交进行的更改:

ALTER SYSTEM SWITCH LOGFILE;

3.3 创建用户帐户

CREATE USER <user name> IDENTIFIED BY <password>;
GRANT create session, alter session, execute_catalog_role, select any dictionary, select any transaction, select any table to <user name>;
GRANT select on v_$logmnr_parameters to <user name>;
GRANT select on v_$logmnr_logs to <user name>;
GRANT select on v_$archived_log to <user name>;
GRANT select on <db>.<table> TO <user name>;

注:把UserB的所有表的查询权限给UserA

select 'grant select on '||owner||'.'||object_name||' to UserA;'
from dba_objects
where owner in ('UserB')
and object_type='TABLE';

3.4 提取日志挖掘字典(重做日志)

仅在非高峰时间提取字典,因为操作会消耗数据库资源

EXECUTE DBMS_LOGMNR_D.BUILD(OPTIONS=> DBMS_LOGMNR_D.STORE_IN_REDO_LOGS);

3.5 挖掘数据

设置当前会话的时间格式:

ALTER SESSION SET NLS_DATE_FORMAT ='DD-MM-YYYY HH24:MI:SS';

设置会话区间,调用过程进行数据挖掘:

Execute DBMS_LOGMNR.START_LOGMNR( STARTTIME => to_date('20-03-2022 21:30:00','DD-MM-YYYY HH24:MI:SS'), ENDTIME => to_date('20-03-2022 22:30:00','DD-MM-YYYY HH24:MI:SS'), OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG          + DBMS_LOGMNR.CONTINUOUS_MINE          + DBMS_LOGMNR.NO_SQL_DELIMITER);

查询操作类型为1,3,2,25的日志相关信息

SELECT SCN,OPERATION_CODE, TIMESTAMP, SQL_REDO, TABLE_NAME,ROLLBACK, ROW_ID  FROM V$LOGMNR_CONTENTS WHERE  SEG_OWNER='HR' AND TABLE_NAME IN ('EMPLOYEES','EMP') AND OPERATION_CODE IN (1,3,2,25);

结束数据挖掘:

Execute  DBMS_LOGMNR.END_LOGMNR;

注意:
V$LOGMNR_CONTENTS视图说明

四、清除归档日志

查看归档日志占用的空间:

select * from v$flash_recovery_area_usage;

查看归档日志的存放地址;

方法一:增大归档日志空间的大小
可以通过下面的方法来调整系统的回闪恢复区大小:
首先是关闭数据库:以SYS身份链接到oracle,执行>shutdown immediate;
启动数据库到mount状态:>startup mount
查看回闪恢复区的大小和存放目标:>show parameter db_recovery_file_dest
修改回闪恢复区的大小>alter system set db_recovery_file_dest_size = 8G(缺省是2G,可以根据实际情况调整大小)
最后打开数据库:>alter database open;

方法二: rman删除

rman target sys/*****@orcl

DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7'; (指定删除7天前的归档日志)

五、代码层面抽取数据

初始化 sql表达式

改变当前会话的格式:

ALTER SESSION SET NLS_DATE_FORMAT =‘DD-MM-YYYY HH24:MI:SS’;

ALTER SESSION SET NLS_TIMESTAMP_FORMAT = ‘YYYY-MM-DD HH24:MI:SS.FF’;

ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ‘.,’;

ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = ‘YYYY-MM-DD HH24:MI:SS.FF TZH:TZM’;

获取当前的scn

SELECT CURRENT_SCN FROM GV$DATABASE;

根据选择的方式,获取cdc初始处理的位置

选择的为LATEST,即获取当前时间为 配置中的startDate

实际上LATEST模式的处理为DATE的一种特殊模式,实际上仍然是按照DATE模式处理

判断数据库的版本以及处理的schema和表
数据库版本:

SELECT version FROM product_component_version;

schema和表

校验schema和表:

当版本大于等于11时,

初始化LogMnr表达式,
预编译:
selectFromLogMnrContents:

SELECT SCN, USERNAME, OPERATION_CODE, TIMESTAMP, SQL_REDO, TABLE_NAME, COMMIT_SCN, SEQUENCE#, CSF, XIDUSN, XIDSLT, XIDSQN, RS_ID, SSN, SEG_OWNER, ROLLBACK, ROW_ID FROM V$LOGMNR_CONTENTS WHERE ((( (SEG_OWNER=‘HR’ AND (TABLE_NAME IN ('EMPLOYEES
'))) ) AND (OPERATION_CODE IN (1,3,2,25))) OR (OPERATION_CODE = 7 OR OPERATION_CODE = 36))

存储过程:
startLogMnrForCommitSCN:
BEGIN DBMS_LOGMNR.START_LOGMNR( STARTSCN => ?, ENDSCN => ?, OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.CONTINUOUS_MINE + DBMS_LOGMNR.NO_SQL_DELIMITER); END;

startLogMnrForData:
BEGIN DBMS_LOGMNR.START_LOGMNR( STARTTIME => ?, ENDTIME => ?, OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.CONTINUOUS_MINE + DBMS_LOGMNR.NO_SQL_DELIMITER); END;

startLogMnrSCNToDate:
BEGIN DBMS_LOGMNR.START_LOGMNR( STARTSCN => ?, ENDTIME => ?, OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.CONTINUOUS_MINE + DBMS_LOGMNR.NO_SQL_DELIMITER); END;

endLogMnr:
BEGIN DBMS_LOGMNR.END_LOGMNR; END;

getTimestampsFromLogMnrContents:
SELECT TIMESTAMP FROM V$LOGMNR_CONTENTS ORDER BY TIMESTAMP

若使用重做日志(数据库的表结构发生变化时启用):


若存储在磁盘

存储在内存中,若解析sql,则需要创建固定线程数的线程池;若不解析sql,则创建单个工作线程的线程池,调用存储过程,获取归档日志数据


向线程池中提交runnable,把record提交导batchMaker

Oracle 补充日志分类和相关操作, logminer cdc实时同步数据变化,提取归档日志进行数据挖掘,相关代码实现相关推荐

  1. ORACLE(Linux版本)实时同步数据到MYSQL(Windows版本)解决方案:OGG

    OGG:Oracle GoldenGate 目录 1.源库(100.100.100.210)与目标库(100.100.100.211)环境 源库环境:Oracle 11.2.0.1.0 + Red H ...

  2. ORACLE(Linux版本)实时同步数据到MYSQL(Linux版本)解决方案:OGG

    OGG:Oracle GoldenGate 目录 1.源库与目标库环境(这里是部署到同一台服务器上) 源库环境:Oracle 11.2.0.1.0 + Red Hat Enterprise Linux ...

  3. linux 误删除mysql表能恢复吗,Linux中误删除数据文件和归档日志的恢复方法

    误删除前,归档日志2个,用户数据4480064条 复制代码 代码如下: [oracle@station90 datafile]$ sqlplus /nolog SQL> conn hr/hr C ...

  4. 通讯录管理系统课设使用c编写基于链表增查删改分组文本操作随程序实时同步

    通讯录管理系统已经有好多人写过了 但是基于文本操作大多数只有从文件中输出和输入并不是即时的 解决方法是将链表里的数据输出以结构体的方式到文本 读入应该以一样的方式 增加个人信息函数定义 void Ad ...

  5. Oracle数据库开启归档日志和补充日志

    文章目录 Oracle数据库开启归档日志和补充日志 重做日志的概念 归档日志 ARCHIVELOG模式 启动归档日志 归档日志的清理 补充日志 Oracle数据库开启归档日志和补充日志 项目中要对Or ...

  6. 正确删除ORACLE归档日志文件

    在controlfile中记录着每一个archivelog的相关信息,当然们在OS下把这些物理文件delete掉后,在我们的 controlfile中仍然记录着这些archivelog的信息,在ora ...

  7. Oracle归档日志(翻译)

    网址:http://cuddletech.com/articles/oracle/node58.html http://cuddletech.com/articles/index.shtml 参考网址 ...

  8. 当ORACLE归档日志满后如何正确删除归档日志

    当ORACLE 归档日志满了后,将无法正常登入ORACLE,需要删除一部分归档日志才能正常登入ORACLE. 一.首先删除归档日志物理文件,归档日志一般都是位于archive目录下,AIX系统下文件格 ...

  9. oracle之 Oracle归档日志管理

    在Oracle中,数据一般是存放在数据文件中,不过数据库与Oracle最大的区别之一就是数据库可以在数据出错的时候进行恢复.这个也就是我们常见的Oracle中的重做日志(REDO FILE)的功能了. ...

最新文章

  1. 父类的析构函数定义为虚函数
  2. iOS程序启动原理(上)
  3. 开始工业物联网项目需要考虑的八大要点
  4. Mangos源码分析(15):游戏对象的实现
  5. [教程]添加yueue.ADOKeycap数据库组件到您的项目
  6. mysql数据库表分区_MySQL数据库之MySQL的分区和分表详解
  7. 精通版本之Subversion
  8. Java基础知识2(字符串)
  9. 苹果平板爱思助手检验安兔兔
  10. 二元函数对xy同时求导_二元函数的连续、可偏导、可微、偏导数连续之间的关系...
  11. 重装电脑?先来个PE盘!
  12. 小O地图EXE版V0.9.5.5 - 功能总览
  13. 日月年时分秒转换为年月日时分秒
  14. python 爬取海量网易云评论并写入数据库
  15. 前端实用的20个css技巧
  16. 完整的系统帮助类Utils
  17. 最强nba体验服显示服务器正在停机,最强NBA体验服
  18. java正则表达式匹配任意中文_java匹配中文的正则表达式
  19. 重叠社区发现-LFM算法
  20. 计算机怎么消除用户密码,电脑开机设置了密码要怎么删除

热门文章

  1. 工作中的方法论(十)
  2. 矩阵键盘硬件设计及软件流程
  3. php标签调用,在自己的php页面中使用dedecms标签的代码示例
  4. uniapp的导航栏自定义返回路径
  5. 《程序员的自我修养》读书笔记
  6. 字节测试开发工程师面经(二面已凉)
  7. 千万不要在领导面前说这五种话
  8. .NET MVC中controler层返回值常见类型
  9. python之:tkinter画哆啦A梦
  10. RoR,再往前走一步