Oracle CDC使用logminer 捕获数据变化

一.前情:

客户需要进行数据同步,从oracle同步到Oracle、greenplum、ignite。由于客户使用的数据库为oracle10,在原项目中不支持,所以这周研究了一周的oracle和logminer,把心得记录下来,也许有用。

从Oracle9i开始,Oracle引入CDC技术,在Oracle9i中CDC只支持同步的数据捕获(synchronous change capture),源数据的变化被实时的捕获,捕获的过程和源数据是同一个事务。它的实现需要源数据支持trigger,所以这种同步的技术会给数据源带来性能的问题。

在Oracle10g中得到改进支持异步方式来捕获变化的数据。在Oracle10g中利用redo log来实现CDC,Redo log是一个记录所有数据库变化的独立的文件。CDC的异步方式是非入侵方式(noninvasive)的实现,对于变化数据的捕获就不需要数据库加入trigger。在CDC中变化的数据被保存在一个变化表中,使用者通过订阅的方式(subscribe)生成一个视图并且通过这个视图来得到这些变化的数据。

二.LogMiner介绍:

Oracle LogMiner作为Oracle数据库组成部分,可以通过SQL界面查询online and archived redo log。Redo log包含数据库活动历史的信息。
详情可翻阅LogMiner的英文文档: Oracle Logminer
本文只介绍使用的步骤;

三.docker部署oracle10:

1.拉取镜像文件

docker pull vkanjilal/oracle10g

2.创建挂载目录

mkdir -p /data/oracle10g

3.创建oracle容器,注意docker容器的时间和系统时间可能会存在不一致,需要在创建时挂载localtime

docker run -d -p 1521:1521 -v /data/oracle10g:/data/oracle -v /etc/localtime:/etc/localtime  --name oracle10g klwang/oracle10g

4.进入容器

docker exec -it oracle10g /bin/bash

5.切换到oracle 用户

su - oracle

6.登录oracle

sqlplus / as sysdba
conn /as sysdba

7.创建内部管理员账号,创建一个用户名

create user 用户名 identified by 密码;

8.将dba权限授权给内部管理员账号

grant connect,resource,dba to 用户名;

9.修改密码规则策略为密码永不过期

ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;

四.安装LogMiner:

对于Oracle 10g,默认情况下LogMiner是不可用的,“By default, Oracle Database does not provide any supplemental logging, which means that by default LogMiner is not usable. Therefore, you must enable at least minimal supplemental logging prior to generating log files which will be analyzed by LogMiner.”
所以,要在10g上使用LogMiner,必须修改如下的参数:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

执行以下两个sql安装dbms_logmnr包和dbms_logmnr_d包。
dbms_logmnr_d包:用于提取字典信息到外部文件或者是联机日志中去。
dbms_logmnr包:包含三个过程:
(1) add_logfile:用来添加/删除用于分析的日志文件。
(2) start_logmnr:用来开启日志分析,而且在9i/10g中,可以开启很多不同的分析选项。
(3) end_logmnr:用来终止分析会话,它将回收LogMiner所占用的内存。

@/u01/app/oracle/product/10.2.0/dbhome2/rdbms/admin/dbmslm.sql
@/u01/app/oracle/product/10.2.0/dbhome2/rdbms/admin/dbmslmd.sql
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

五、使用LogMiner工具

1、修改系统初始化参数
数据字典文件是一个文本文件,使用包DBMS_LOGMNR_D来创建。如果分析的数据库中的表有变化,影响到库的数据字典也发生变化,这时就需要重新创建该字典文件。另外一种情况是在分析另外一个数据库文件的重作日志时,也必须要重新生成一遍被分析数据库的数据字典文件。

Oracle 8i中需要修改init.ora文件,添加一个UTL_FILE_DIR参数,此参数为数据字典文件在数据库服务器上的存放目录。如:UTL_FILE_DIR=(/oracle/logs)

docker exec -it 容器id /bin/bash 

创建文件mkdir -p /oracle/logs
对于此文件赋权 chmod 777 /oracle/logs

show parameter pfile

PFILE:文本参数文件(TEXT PARAMETER FILE)又叫静态参数文件,ASCII文本文件
SPFILE:服务器参数文件(SERVER PARAMETER FILE)。二进制文件
从Oracle9i开始,spfile被引入Oracle数据库,Oracle首选spfile<ORACLE_SID>.ora文件作为启动参数文件;如果该文件不存在,Oracle选择spfile.ora文件;如果前两者都不存在,Oracle将会选择init<ORACLE_SID>.ora文件;如果以上三个文件都不存在,Oracle将无法创建和启动instance。
Oracle在启动过程中,会在特定的路径中寻找参数文件,在Unix/Linux下的路径为$ORACLE_HOME/dbs目录

alter system set UTL_FILE_DIR='/oracle/logs' scope=spfile;
 
shutdown immediate;
startup;

2、创建数据字典文件

begin dbms_logmnr_d.build(dictionary_filename=>'logminer_dict10g.dat',dictionary_location=>'/oracle/logs');end;
/

–在d:\oracle\logs目录下建立一个文件名为logminer_dict10g.dat的数据字典文件。

–此时在d:\oracle\logs目录下生成了一个文件名为logminer_dict10g.dat的数据字典文件。

3、创建要分析的redo log文件列表
通过v$logfile 查找 数据库的 redo log file 和组;

select * from v$logfile;

–创建第一个文件

begin dbms_logmnr.add_logfile(options=>dbms_logmnr.new,logfilename=>'/u02/orcl/orcl/redo01.log');end;
/

–增加其他的文件

begin dbms_logmnr.add_logfile(options=>dbms_logmnr.addfile,logfilename=>'/u02/orcl/orcl/redo02.log');end;
/
begin dbms_logmnr.add_logfile(options=>dbms_logmnr.addfile,logfilename=>'/u02/orcl/orcl/redo03.log');end;
/

–提示:Options=>dbms_logmnr.new、addfile、removefile的三个参数,分别是新建、添加、删除日志。
–以上添加了Oracle 10g 中的3个在线redo log文件进行分析。

4、使用LogMiner进行日志分析
1)无限制条件
方法

begin dbms_logmnr.start_logmnr(dictfilename=>'/oracle/logs/logminer_dict10g.dat');end;/

–此处要求指定正确的数据字典文件进行分析,否则解析出来的sql日志中的对象名称和字段名称不是直观的名称。另外如果创建了新表或者增加了新列,那么需要重建数据字典文件然后再进行分析。

2)有限制条件

通过对过程DBMS_ LOGMNR.START_LOGMNR中几个不同参数的设置,可以缩小要分析日志文件的范围。

参数 参数类型 默认值 含义
StartScn 数字型(Number) 0 分析重作日志中SCN>=StartScn日志文件部分
EndScn 数字型(Number) 0 分析重作日志中SCN<=EndScn日志文件部分
StartTime 日期型(Date) 1998-01-01 分析重作日志中时间戳>=StartTime的日志文件部分
EndTime 日期型(Date) 2988-01-01 分析重作日志中时间戳<=EndTime的日志文件部分

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

查询logminer日志时间

select LOG_ID,FILENAME,TO_CHAR(LOW_TIME,'DD-MON-YYYY HH24:MI:SS'),TO_CHAR(HIGH_TIME,'DD-MON-YYY Y HH24:MI:SS') from v$logmnr_logs;

时间范围内的日志

begin dbms_logmnr.start_logmnr(dictfilename=>'/oracle/logs/logminer_dict10g.dat',starttime=>to_date('01-07-2020 16:50:06','DD-MM-YYYY HH24:MI:SS') ,endtime=>to_date('01-07-2020 16:50:','DD-MM-YYYY HH24:MI:SS'));end;
/
begin dbms_logmnr.start_logmnr(dictfilename=>'/oracle/logs/logminer_dict10g.dat',starttime=>to_date('29-06-2020 12:43:07','DD-MM-YYYY HH24:MI:SS') ,endtime=>to_date('30-06-2020 03:21:52','DD-MM-YYYY HH24:MI:SS') );end;
/
begin dbms_logmnr.start_logmnr(dictfilename=>'/oracle/logs/logminer_dict10g.dat',starttime=>to_date(' 01-07-2020 17:48:28','DD-MM-YYYY HH24:MI:SS') ,endtime=>to_date(' 01-07-2020 17:49:34','DD-MM-YYYY HH24:MI:SS'));end;
/

核心视图1详解
核心视图2详解

5、观察分析结果
到现在为止,我们已经分析得到了重做日志文件中的内容。动态性能视图v$logmnr_contents包含LogMiner分析得到的所有的信息。

SELECT sql_redo    FROM    v$logmnr_contents; 

如果我们仅仅想知道某个用户对于某张表的操作,可以通过下面的SQL查询得到,该查询可以得到用户DB_ZGXT对表SB_DJJL所作的一切工作。

SELECT sql_redo FROM v$logmnr_contents WHERE username=用户名 AND tablename=表; 

需要强调一点的是,视图v$logmnr_contents中的分析结果仅在运行过程’dbms_logmrn.start_logmnr’这个会话的生命期中存在。这是因为所有的LogMiner存储都在PGA内存中,所有其他的进程是看不到它的,同时随着进程的结束,分析结果也随之消失。
最后,使用过程DBMS_LOGMNR.END_LOGMNR终止日志分析事务,此时PGA内存区域被清除,分析结果也随之不再存在。

SELECT SCN, USERNAME, OPERATION_CODE, TIMESTAMP, SQL_REDO, TABLE_NAME, CSCN, SEQUENCE#, CSF, XIDUSN, XIDSLT, XIDSQN, RS_ID, SSN, SEG_OWNER, ROLLBACK, ROW_ID  FROM V$LOGMNR_CONTENTS WHERE  ((( (SEG_OWNER='SHENFEI' AND (TABLE_NAME IN ('CZ'))) ) AND (OPERATION_CODE IN (1,3,2,25,5))) OR (OPERATION_CODE = 7 OR OPERATION_CODE = 36)) ;

注意—cscn 和oracle11中的commited-scn功能相同

6、结束监控
–在sys用户 监视的命令窗口执行如下语句结束监视:

begin
dbms_logmnr.end_logmnr;
end;
/

7、遇到的问题

查看数据库版本 select version from product_component_version;

(1)

空间不足,日志没有归档,执行命令:

alter database clear unarchived logfile group 3;
alter database open;

(2)清除日志空间
查看归档日志占用的空间:select * from v$flash_recovery_area_usage;
select * from v$recovery_file_dest; --查看归档日志的存放地址;

方法一:增大归档日志空间的大小
可以通过下面的方法来调整系统的回闪恢复区大小:
首先是关闭数据库:以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删除

(2)添加
如果你的主键或唯一索引是组合的(复合的),就需要为表配置supplemental log,否则就不必,也就是说,如果你的所有表的主键是单列的,那你根本就不必去理会它是什么意思.

猜你喜欢

转载自blog.csdn.net/javahelpyou/article/details/107082758