第 1 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
LogMiner 配置使用手册
1 Logminer 简介
1.1 LogMiner介绍
Oracle LogMiner 是 Oracle 公司从产品 8i 之后提供的一个实际很是有用的分析工具,使
用该工具能够轻松得到 Oracle 在线/归档日志文件中的具体内容,特别是该工具能够分析出所
有对于数据库操做的 DML 和 DDL 语句。该工具特别适用于调试、审计或者回退某个特定的事
务。
LogMiner分析工具其实是由一组PL/SQL包和一些动态视图(Oracle8i内置包的一部分)
组成,它做为 Oracle 数据库的一部分来发布是 8i 产品提供的一个彻底免费的工具。但该工具和
其余Oracle 内建工具相比使用起来显得有些复杂,主要缘由是该工具没有提供任何的图形用户
界面(GUI)。
1.2 LogMiner做用
在 Oracle 8i 以前,Oracle 没有提供任何协助数据库管理员来读取和解释重做日志文件内容
的工具。系统出现问题,对于一个普通的数据管理员来说,惟一能够做的工做就是将全部的log
文件打包,而后发给 Oracle 公司的技术支持,而后静静地等待 Oracle 公司技术支持给咱们最
后的答案。然而从8i之后,Oracle 提供了这样一个强有力的工具--LogMiner。
LogMiner 工具便可以用来分析在线,也能够用来分析离线日志文件,便可以分析自己本身
数据库的重做日志文件,也能够用来分析其余数据库的重做日志文件。
总的说来,LogMiner工具的主要用途有:
1. 跟踪数据库的变化:能够离线的跟踪数据库的变化,而不会影响在线系统的性能。
2. 回退数据库的变化:回退特定的变化数据,减小 point-in-time recovery 的执行。
3. 优化和扩容计划:可经过分析日志文件中的数据以分析数据增加模式
1.3 使用详解
1.3.1 安装LogMiner
在使用 LogMiner 以前须要确认 Oracle 是否带有进行 LogMiner 分析包,通常来讲第 2 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
Windows操做系统 Oracle10g 以上都默认包含。若是不能确认,能够 DBA身份登陆系统,查
看系统中是否存在运行LogMiner所须要的dbms_logmnr、dbms_logmnr_d包,若是没有需
要安装 LogMiner工具,必须首先要运行下面这样两个脚本:
一、$ORACLE_HOME/rdbms/admin/dbmslm.sql
二、$ORACLE_HOME/rdbms/admin/dbmslmd.sql.
这两个脚本必须均以DBA用户身份运行。其中第一个脚本用来建立DBMS_LOGMNR 包,
该包用来分析日志文件。第二个脚本用来建立DBMS_LOGMNR_D包,该包用来建立数据字典
文件。
建立完毕后将包括以下过程和视图:
类型 过程名 用途
过程 Dbms_logmnr_d.build 建立一个数据字典文件
过程 Dbms_logmnr.add_logfile 在类表中增长日志文件以供分析
过程 Dbms_logmnr.start_logmnr 使用一个可选的字典文件和前面肯定要分析日志
文件来启动LogMiner
过程 Dbms_logmnr.end_logmnr 中止LogMiner分析
视图 V$logmnr_dictionary 显示用来决定对象ID 名称的字典文件的信息
视图 V$logmnr_logs 在LogMiner启动时显示分析的日志列表
视图 V$logmnr_contents LogMiner启动后,可使用该视图在 SQL 提示
符下输入SQL语句来查询重作日志的内容
1.3.2 建立数据字典文件
LogMiner 工具其实是由两个新的 PL/SQL 内建包((DBMS_LOGMNR 和 DBMS_
LOGMNR_D)和四个 V$动态性能视图(视图是在利用过程 DBMS_LOGMNR.START_LOGMNR
启动 LogMiner 时建立)组成。在使用 LogMiner 工具分析 redo log 文件以前,可使用
DBMS_LOGMNR_D 包将数据字典导出为一个文本文件。该字典文件是可选的,可是若是没有
它,LogMiner 解释出来的语句中关于数据字典中的部分(如表名、列名等)和数值都将是 16
进制的形式,咱们是没法直接理解的。例如,下面的sql 语句:
INSERT INTO dm_dj_swry (rydm, rymc) VALUES (00005, '张三');
LogMiner解释出来的结果将是下面这个样子,
insert into Object#308(col#1, col#2) values (hextoraw('c30rte567e436'),
hextoraw('4a6f686e20446f65'));
建立数据字典的目的就是让 LogMiner 引用涉及到内部数据字典中的部分时为他们实际的
名字,而不是系统内部的 16 进制。数据字典文件是一个文本文件,使用包 DBMS_LOGMNR_D第 3 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
来建立。若是咱们要分析的数据库中的表有变化,影响到库的数据字典也发生变化,这时就须要
从新建立该字典文件。另一种状况是在分析另一个数据库文件的重做日志时,也必需要从新
生成一遍被分析数据库的数据字典文件。
建立数据字典文件以前须要配置LogMiner文件夹:
CREATE DIRECTORY utlfile AS 'D:\oracle\oradata\practice\LOGMNR';
alter system set utl_file_dir='D:\oracle\oradata\practice\LOGMNR' scope=spfile;
建立字典文件须要以DBA用户登陆,建立到上面配置好的LogMiner文件夹中:
CONN LOGMINER/ LOGMINER@PRACTICE AS SYSDBA
EXECUTE dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_
location =>'D:\oracle\oradata\practice\LOGMNR');
1.3.3 加入需分析的日志文件
Oracle 的 LogMiner 能够分析在线(online)和归档(offline)两种日志文件,加入分析
日志文件使用 dbms_logmnr.add_logfile 过程,第一个文件使用 dbms_logmnr.NEW 参数,
后面文件使用 dbms_logmnr.ADDFILE 参数。
一、建立列表
BEGIN
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\REDO03.LO
G',options=>dbms_logmnr.NEW);
END;
/
二、添加其余日志文件到列表
BEGIN
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\ARCHIVE\A
RC00002_0817639922.001',options=>dbms_logmnr.ADDFILE);
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\ARCHIVE\A
RC00003_0817639922.001',options=>dbms_logmnr.ADDFILE);
END;
/
1.3.4 使用LogMiner 进行日志分析
Oracle 的 LogMiner 分析时分为无限制条件和限制条件两种,无限制条件中分析全部加入
到分析列表日志文件,限制条件根据限制条件分析指定范围日志文件。
第 4 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
一、无限制条件
EXECUTE
dbms_logmnr.start_logmnr(dictfilename=>'D:\oracle\oradata\practice\LOGMNR\
dictionary.ora');
二、有限制条件
经过对过程DBMS_ LOGMNR.START_LOGMNR中几个不一样参数的设置(参数含义见表1),
能够缩小要分析日志文件的范围。经过设置起始时间和终止时间参数咱们能够限制只分析某一时
间范围的日志。
参数 参数类型 默认值 含义
StartScn 数字型 0 分析重做日志中SCN≥StartScn 日志文件部分
EndScn 数字型 0 分析重做日志中SCN≤EndScn 日志文件部分
StartTime 日期型 1998-01-01 分析重做日志中时间戳≥StartTime 的日志文件
部分
EndTime 日期型 2988-01-01 分析重做日志中时间戳≤EndTime 的日志文件部
分
DictFileName 字符型 字典文件该文件包含一个数据库目录的快照。
以下面的例子,咱们仅仅分析 2013 年6 月8日的日志,:
EXECUTE dbms_logmnr.start_logmnr(
DictFileName => dictfilename=>'D:\..\practice\LOGMNR\dictionary.ora',
StartTime =>to_date('2013-6-8 00:00:00','YYYY-MM-DD HH24:MI:SS')
EndTime =>to_date(''2013-6-8 23:59:59','YYYY-MM-DD HH24:MI:SS '));
也能够经过设置起始SCN和截至 SCN来限制要分析日志的范围:
EXECUTE dbms_logmnr.start_logmnr(
DictFileName =>'D:\..\practice\LOGMNR\dictionary.ora',
StartScn =>20,
EndScn =>50);
1.3.5 观察分析结果(v$logmnr_contents)
到如今为止,咱们已经分析获得了重做日志文件中的内容。动态性能视图
v$logmnr_contents包含 LogMiner分析获得的全部的信息。
SELECT sql_redo FROM v$logmnr_contents;
若是咱们仅仅想知道某个用户对于某张表的操做,能够经过下面的 SQL 查询获得,该查询
能够获得用户 LOGMINER对表EMP所做的一切工做。
SELECT sql_redo FROM v$logmnr_contents WHERE username='LOGMINER' AND 第 5 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
tablename='EMP';
序号 名称 含义
1 SCN 特定数据变化的系统更改号
2 TIMESTAM 数据改变发生的时间
3 COMMIT_TIMESTAMP 数据改变提交的时间
4 SEG_OWNER 数据发生改变的段名称
5 SEG_NAME 段的全部者名称
6 SEG_TYPE 数据发生改变的段类型
7 SEG_TYPE_NAME 数据发生改变的段类型名称
8 TABLE_SPACE 变化段的表空间
9 ROW_ID 特定数据变化行的ID
10 SESSION_INFO 数据发生变化时用户进程信息
11 OPERATION 重作记录中记录的操做(如 INSERT)
12 SQL_REDO 能够为重作记录重作指定行变化的 SQL 语句(正
向操做)
13 SQL_UNDO 能够为重作记录回退或恢复指定行变化的 SQL
语句(反向操做)
须要强调一点的是,视图 v$logmnr_contents 中的分析结果仅在咱们运行过程
'dbms_logmrn.start_logmnr'这个会话的生命期中存在。这是由于全部的 LogMiner 存储都在
PGA内存中,全部其余的进程是看不到它的,同时随着进程的结束,分析结果也随之消失。
最后,使用过程DBMS_LOGMNR.END_LOGMNR终止日志分析事务,此时 PGA内存区域
被清除,分析结果也随之再也不存在。
2 数据同步 Oracle 数据库设置
Oracle 数据使用 LogMiner查看执行 SQL语句,其中须要进行以下四步骤是指:
1. 设置数据库为归档模式;
2. 设置 LogMiner字典文件路径等;
3. 建立数据同步用户(如用户名为 LOGMINER,该用户拥有DBA权限);
4. 验证配置是否成功; 第 6 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
2.1 设置数据库为归档模式
2.1.1 查看数据库是否为归档模式
使用 SqlPlus或者命令行界面链接数据库(如下以命令行界面操做)
--进入SqlPlus程序
sqlplus /nolog
--使用DBA用户登陆到源数据库中
conn system/system@practic as sysdba
--查看PRACTICE数据库是否处于归档模式
SELECT dbid, name, log_mode FROM v$database;
或者 ARCHIVE LOG LIST;
若是显示数据库显示为归档模式,则设置数据库为归档模式可跳过;若是显示数据库为非归档模
式则须要进行如下设置。
上图显示数据库未进行归档,须要进行归档设置。 第 7 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
2.1.2 设置归档模式
建立 ARCHIVE 文件夹,ARCHIVE 文件夹路径根据所在服务器进行设置,在下面操做中设置为"
D:\oracle\oradata\practice\ARCHIVE"
--设置归档日志文件路径
ALTER SYSTEM SET log_archive_dest="D:\oracle\oradata\practice\ARCHIVE";
--日志文件名称格式:
ALTER SYSTEM SET log_archive_format="ARC%S_%R.%T" SCOPE=SPFILE;
--修改完毕后,关闭数据库,以 MOUNT方式启动
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
--设置数据库为归档模式
ALTER DATABASE ARCHIVELOG; 第 8 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
(注意:若是重启数据失败,请参考第4 章节异常问题处理)
2.1.3 验证归档是否设置成功
--查看PRACTICE数据库是否处于归档模式
SELECT dbid, name, log_mode FROM v$database;
或者 ARCHIVE LOG LIST;
--验证参数设置是否起做用
SELECT dest_id, status, destination FROM v$archive_dest WHERE dest_id =1;
--在参数文件设置已经起做用,打开数据库 第 9 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
ALTER DATABASE OPEN;
2.2 LogMiner设置
2.2.1 建立LogMiner 文件夹
建立 LOGMNR文件夹,路径为"D:\oracle\oradata\practice\LOGMNR"
2.2.2 设置LogMiner 字典文件路径
--建立数据字典文件
CREATE DIRECTORY utlfile AS 'D:\oracle\oradata\practice\LOGMNR';
alter system set utl_file_dir='D:\oracle\oradata\practice\LOGMNR' scope=spfile; 第 10 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
2.2.3 开启LogMiner 日志补充模式
--建立数据字典文件
alter database add supplemental log data;
2.2.4 重启数据库验证
--修改完毕后,关闭数据库,以 MOUNT方式启动
SHUTDOWN IMMEDIATE;
STARTUP;
--查看Logminer文件夹是否设置
SHOW PARAMETER utl_file_dir; 第 11 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
2.3 建立数据同步用户
在数据库建立LOGMINER用户,该用户须要具备DBA权限
--在源数据库建立 LOGMINER用户,并赋予 DBA权限
CREATE USER LOGMINER IDENTIFIED BY LOGMINER;
GRANT CONNECT, RESOURCE,DBA TO LOGMINER;
3 使用 LogMiner 读取日志例子
在使用 LogMiner 读取归档/在线日志须要按照第 2 章节进行设置,设置完毕后能够对归档
和在线日志进行分析。特别是须要开启 LogMiner 日志补充模式,若是没有开始 LogMiner 补
充模式将没法查看 DDL语句,按照测试结果看,只有开始 LogMiner日志补充模式后,才能查
看 DDL语句,在此以前进行DDL将没法进行查看。 第 12 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
3.1 使用LogMiner 读取在线日志
3.1.1 测试数据准备
--以LOGMINER用户登陆(非DBA登陆)建立 AAAAA表(Oracle11g请注意用户名、密码大
小写)
CONNECT LOGMINER/LOGMINER@PRACTICE
CREATE TABLE AAAAA(field001 varchar2(100));
INSERT INTO AAAAA (field001) values ('000000');
INSERT INTO AAAAA (field001) values ('0000010');
commit;
3.1.2 建立数据字典文件
数据库对象发生变化,须要从新建立数据字典文件
--以LOGMINER用户(DBA权限)登陆,生成字典文件
CONN LOGMINER/LOGMINER@PRACTICE AS SYSDBA
EXECUTE dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_loca
tion =>'D:\oracle\oradata\practice\LOGMNR');
3.1.3 确认当前处于联机状态的日志文件
--须要确认当前处于联机状态的日志文件
SELECT group#, sequence#, status, first_change#, first_time FROM V$log ORDER BY first_change#; 第 13 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
从上图能够看出在线日志REDO03 处于ACTIVE状态中
3.1.4 加入需分析的日志文件
--加入解析在线日志文件
BEGIN
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\REDO03.LOG',opti
ons=>dbms_logmnr.NEW);
END;
/
3.1.5 使用LogMiner 进行分析
--启动LogMiner进行分析
EXECUTE
dbms_logmnr.start_logmnr(dictfilename=>'D:\oracle\oradata\practice\LOGMNR\dictio
nary.ora');
第 14 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
3.1.6 观察分析结果
--查询相关操做日志
SELECT sql_redo, sql_undo, seg_owner
FROM v$logmnr_contents
WHERE seg_name='AAAAA'
AND seg_owner='LOGMINER';
3.2 使用LogMiner 读取归档日志
3.2.1 测试数据准备
--以 LOGMINER 用户登陆(非 DBA 权限)建立 EMP 表(Oracle11g 请注意用户名、密码大小
写)
CONN LOGMINER/ LOGMINER@PRACTICE
CREATE TABLE EMP
(EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY, 第 15 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2));
--插入EMP数据
INSERT INTO EMP VALUES
(7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);
INSERT INTO EMP VALUES
(7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
INSERT INTO EMP VALUES
(7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
INSERT INTO EMP VALUES
(7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);
COMMIT;
--从v$log视图中找出日志文件的序号
CONNECT system/system@practice as sysdba
ALTER SYSTEM SWITCH LOGFILE;
select sequence#, FIRST_CHANGE#, NEXT_CHANGE#,name from v$archived_log order
by sequence# desc; 第 16 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
3.2.2 建立数据字典文件
确保按照 2.2 进行 logMiner设置
--以LOGMINER用户(DBA权限)登陆,生成字典文件
CONN LOGMINER/ LOGMINER@PRACTICE AS SYSDBA
EXECUTE dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_loca
tion =>'D:\oracle\oradata\practice\LOGMNR');
3.2.3 加入需分析的日志文件
--加入解析日志文件
BEGIN
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\ARCHIVE\ARC000
02_0817639922.001',options=>dbms_logmnr.NEW);
END;
/ 第 17 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
3.2.4 使用LogMiner 进行分析
--启动LogMiner进行分析
EXECUTE
dbms_logmnr.start_logmnr(dictfilename=>'D:\oracle\oradata\practice\LOGMNR\dictio
nary.ora');
3.2.5 观察分析结果
--查询相关操做日志
SELECT sql_redo, sql_undo
FROM v$logmnr_contents
WHERE seg_name='EMP'
AND seg_owner='LOGMINER'; 第 18 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
4 其余
4.1 异常问题处理
4.1.1 出现ORA-12514错误
若是出现 ORA-12514 错误时,以下图所示: 第 19 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
须要修改 listerner.ora 文件,具体在 Oracle 安装目录\NETWORK\ADMIN 下,当前操做为"
D:\oracle\product\10.2.0\db_1\NETWORK\ADMIN\listener.ora "加入以下设置
(SID_DESC =
(GLOBAL_DBNAME = practice)
(ORACLE_HOME = D:\oracle\product\10.2.0\db_1)
(SID_NAME = practice)
)
设置后须要从新启动TNSListener,便可生效
4.1.2 出现ORA-16018错误
若是出现 ORA-16018 错误时,以下图所示:
该问题是数据库开启了闪回功能,归档文件默认状况下是保存到闪回路径中,简单的处理方式是
在设置归档路径中加入scope=spfile 参数
--设置归档日志文件路径
ALTER SYSTEM SET log_archive_dest="D:\oracle\oradata\practice\ARCHIVE"
scope=spfile;
此时查看闪回路径,该路径并未影响,只不过闪回文件和归档文件保存到各自文件夹中
java
第 1 页 共 7 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
Oracle Logminer 性能测试
1 测试介绍
1.1 测试目的
经过模拟不一样环境下 LogMiner 解析联机/归档日志文件运行状况,经过测试所获取
的数据分析,经过对如下两点的验证来肯定经过 LogMiner技术技术可行性:
一、在日志文件不一样大小、不一样数据压力状况下对数据库服务器内存、CPU 的影响;
二、并经过查询 LogMiner 的动态表和实际物理表中数据数目是否一致,验证其准确
性。
1.2 测试环境
用途及说明 硬件配置 软件配置 其它说明
数据库服务器
型号:T420i
处理器:Intel(R)core(TM) i5
CPU M430
主频:2.2G
内存:2G
硬盘:300G
操做系统:WindowXP
数据库及版本:Oracle10.2g
IP地址:10.88.54.83
测试机
型号:T420i
处理器:Intel(R)core(TM) i5
CPU M430
主频:2.2GHz
内存:1.8 GB
显示器:1280*800 宽屏
操做系统:windows xp
浏览器及版本:ie8
1.3 测试方案
1.3.1 性能影响(针对目标一)
为了模拟实际运行环境,加入了 Logminer运行背景环境,分别测试数据库在无操做、
300 个插入/秒操做、500 个插入/秒操做状况下运行状况,而且对比日志文件50M、100M第 2 页 共 7 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
大小下运行状况
联机日志大小 读取文件个数 运行做业数目 插入数据量
方案一 50M
1 个 0 个 0 笔/秒
3 个 0 个 0 笔/秒
5 个 0 个 0 笔/秒
10 个 0 个 0 笔/秒
方案二 50M
1 个 500 个 估计300 笔/秒
3 个 500 个 估计300 笔/秒
5 个 500 个 估计300 笔/秒
10 个 500 个 估计 300 笔/秒
方案三 50M(未运行
CPU80%,680M)
1 个 1000 个 估计 500 笔/秒
3 个 1000 个 估计500 笔/秒
5 个 1000 个 估计500 笔/秒
10 个 1000 个 估计 500 笔/秒
方案四 100M(未运行
CPU25%,464M)
1 个 500 个 估计300 笔/秒
3 个 500 个 估计300 笔/秒
5 个 500 个 估计300 笔/秒
10 个 500 个 估计 300 笔/秒
1.3.2 准确性(针对目标二)
一、数据类型
序号 数据类型 是否支持 问题处理
1 BINARY_DOUBLE 8.1 及以上
2 BINARY_FLOAT 8.1 及以上
3 CHAR 8.1 及以上
4 DATE 8.1 及以上
需设置时间格式,不然只能同步日期
alter system set
nls_date_format='yyyy-MM-dd
HH24:mi:ss' scope=spfile;
5 INTERVAL DAY 8.1 及以上
6 INTERVAL YEAR 8.1 及以上
7 NUMBER 8.1 及以上
8 NVARCHAR2 8.1 及以上
9 RAW 8.1 及以上
10 TIMESTAMP 8.1 及以上
11 TIMESTAMP 8.1 及以上 第 3 页 共 7 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
WITH LOCAL
TIME ZONE
12 VARCHAR2 8.1 及以上
13 LONG 9.2 及以上
14 CLOB 10.1 及以上 须要设置以下:
ALTER DATABASE ADD SUPPLEMENTAL
LOG DATA (ALL) COLUMNS;
插入时分为两条语句,另外插入二进制数据
未进行测试
15 BLOB 10.0 及以上
二、DDL语句测试(未测试完毕)
序号 类型 是否支持
1 建立表(Create table) 支持
2 删除表(Drop table)
支持,出现两个语句,首先修改表
名为临时表名,而后删除该临时表
监控该类型须要进行合并处理
3 建立做业(Create job) 不支持
4 建立序列(Create sequence) 支持
5 建立存储过程(Create pocedure) 支持
6 增长字段(alter table TABLE add column) 支持
7 删除字段(alter table emp drop column) 支持
8 修改字段(alter table emp modify column) 支持
9 修改列名(alter table rename column) 支持
10 修改表名(rename emp to TABLE) 支持
11 清除表数据(truncate table TABLE) 支持
12 删除表(drop table TABLE) 支持
13 恢复被删除的表(Flashback table TABLE to before
drop) 支持
14 NOT NULL约束(alter table TABLE modify
COLUMN not null) 支持
15 UNIQUE 约束 支持
16 PRIMARY KEY 约束 支持
17 FOREIGN KEY 约束 支持
18 CKECK 约束 支持
19 禁用/激活约束 支持
20 删除约束 支持
21 建立不惟一索引 支持 第 4 页 共 7 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
22 建立惟一索引 支持
23 建立位图索引 支持
24 建立反序索引 支持
25 建立函数索引 支持
26 修改索引 支持
27 合并索引 支持
28 重建索引 支持
29 删除索引 支持
30 建立视图(CREATE VIEW) 支持
31 修改视图(CREATE OR REPLACE VIEW) 支持
32 删除视图(DROP VIEW) 支持
33 建立序列(CREATE SEQUENCE) 支持
34 修改序列(ALTER SEQUENCE) 支持
35 删除序列(DROP SEQUENCE) 支持
三、其余问题测试
序号 问题 现象及处理方式
1 主子表插入数据测试 可以正常插入及同步
2 事务提交(commit、rollback)
可以看到提交和未提交的内容,考虑在产品设计
中加入
DBMS_LOGMNR.COMMITTED_DATA_ON
LY
参数,该参数只读取已经提交事务
3 批量更新时,影响多条数据,在联机日志
中每一条更新数据对应生成一条语句 不影响,可同步获取再执行
4 更新和删除语句中带rowid
加入去除rowid 参数
dbms_logmnr.NO_ROWID_IN_STMT
5
2 测试结论
2.1 测试初步结论
1. 从性能影响测试中能够看出: 第 5 页 共 7 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
a) logminer加载分析过程随机器根据负载不一样在 6~21 秒完成;
b) 加载分析过程并不随日志文件个数增长在时间、CPU、内存有较大变化;
c) 加载分析过程当中受分析日志文件个数最大是内存,其次是 CPU,耗时应影响较小;
2. 从准确性测试来看
a) 经过设置基本上可以获取 DML语句(其中 LOB 字段还须要进行测试);
b) 从现有状况来看,DDL支持并不充分,须要进一步测试;
第 6 页 共 7 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
联机日志大小
读取
文件
个数
运行做
业数目 插入数据量
生成字典
文件 加载处理 分析处理 log_content
s
数据量
大
小
(M)
时
间
(秒)
耗时
(秒)
CPU(%
)
内存
(M)
耗时
(秒)
CPU(%
)
内存
(M)
方案
一 50M
1 个 0 个 0 笔/秒
47.
5
12.
7
1 1 309 5.5 25 438 600
3 个 0 个 0 笔/秒 1 1 309 5.7 25 444 222,236
5 个 0 个 0 笔/秒 1 1 326 5.6 25 445 492,606
10个 0 个 0 笔/秒 1 1 326 5.6 25 445 1,149,284
方案
二 50M
1 个 500 个 估计300 笔/秒
47.
5 20
1 26 391 6.7 35 530 111,328
3 个 500 个 估计300 笔/秒 1 21 473 6.4 37 619 372,389
5 个 500 个 估计300 笔/秒 1 25 534 6.8 44 692 622,390
10个 500 个 估计300 笔/秒 1 30 624 6.7 39 780 1,254,748
方案
三
50M(未运行
CPU80%,680M)
1 个 1000个 估计500 笔/秒
47.
5
54.
7
3.5 71 688 15 80 806 35,892
3 个 1000个 估计500 笔/秒 1.5 41 688 14.4 78 777 384,743
5 个 1000个 估计500 笔/秒 1 68 687 75 805 652,148
10个 1000个 估计500 笔/秒 10 80 689 13.2 79 806 1,295,158
方案
四
50M(未运行
CPU80%,667M)
1 个 2000个 估计1000笔/秒
47.
5
73.
7
5.5 84 691 14.6 78 808 133,844
3 个 2000个 估计1000笔/秒 11.4 70 691 12 75 809 390,029
5 个 2000个 估计1000笔/秒 5.5 76 690 13.6 76 806 668,013
10个 2000个 估计1000笔/秒 6.1 40 690 15.4 88 809 1,335,587
方案 100M(未运行 1 个 500 个 估计300 笔/秒 23. 8.7 0.8 26 484 4.1 30 573 268,715 第 7 页 共 7 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
五 CPU25%,464M) 3 个 500 个 估计300 笔/秒 8 0.9 25 534 3.2 36 622 768,989
5 个 500 个 估计300 笔/秒 0.9 27 581 3.2 35 662 1,324,447
10个 500 个 估计300 笔/秒 1.1 29 690 5.2 35 763 2,619,322 sql
第 1 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
使用 Oracle Logminer 同步 Demo
1 Demo介绍
1.1 Demo设想
前面介绍了 Oracle LogMiner 配置使用以及使用 LogMiner 进行解析日志文件性能,在这
篇文章中将利用LogMiner进行数据同步,实现从源目标数据库到目标数据库之间的数据同步。
因为LogMiner支持的版本是8.1及以上,因此进行数据同步的Oracle数据库版本也必须是8.1
及以上。
固然在本文中介绍的是LogMiner进行数据同步例子,也能够利用LogMiner进行数据审计、
数据操做追踪等功能,因为这些从操做原理来讲是一致,在本文不作讨论。
1.2 框架图
第 2 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
1.3 流程图
配置阶段
一、 控制端:指定源端、目标端数据库信息、LOGMINER同步时间等配置信息;
获取源端同步数据
二、 控制台:经过定时轮询的方式检测是否到达数据同步时间,若是是则进行数据同步,否
则继续进行轮询;
三、 源数据库:定时加载数据库归档日志文件到动态表v$logmnr_contents中;
四、 源数据库:根据条件读取指定sql 语句;
目标端数据入库
五、 源数据库:执行sql 语句。
2 代码分析
2.1 目录及环境配置
在该 Demo 项目中须要引入 Oracle JDBC 驱动包,具体项目分为四个类: 第 3 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
1. Start.java:程序入口方法;
2. SyncTask.java:数据同步 Demo 核心,生成字典文件和读取日志文件、目标数据库执
行SQL语句等;
3. DataBase.java:数据库操做基础类;
4. Constants.java:源数据库、目标数据库配置、字典文件和归档文件路径。
2.2 代码分析
2.2.1 Constants.java
在该类中设置了数据同步开始 SCN号、源数据库配置、目标数据库配置以及字典文件/日志
文件路径。须要注意的是在源数据库配置中有两个用户:一个是调用 LogMiner 用户,该用户
须要拥有 dbms_logmnr、dbms_logmnr_d两个过程权限,在该 Demo 中该用为为sync;另
外一个为 LogMiner读取该用户操做 SQL语句,在该Demo 中该用为为 LOGMINER。
package com.constants;
/**
* [Constants]|描述:Logminer配置参数
* @做者: ***
* @日期: 2013-1-15 下午01:53:57
* @修改历史:
*/
public class Constants {
/** 上次数据同步最后SCN号 */
public static String LAST_SCN = "0"; 第 4 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
/** 源数据库配置 */
public static String DATABASE_DRIVER="oracle.jdbc.driver.OracleDriver";
public static String
SOURCE_DATABASE_URL="jdbc:oracle:thin:@127.0.0.1:1521:practice";
public static String SOURCE_DATABASE_USERNAME="sync";
public static String SOURCE_DATABASE_PASSWORD="sync";
public static String SOURCE_CLIENT_USERNAME = "LOGMINER";
/** 目标数据库配置 */
public static String SOURCE_TARGET_URL="jdbc:oracle:thin:@127.0.0.1:1521:target";
public static String SOURCE_TARGET_USERNAME="target";
public static String SOURCE_TARGET_PASSWORD="target";
/** 日志文件路径 */
public static String LOG_PATH = "D:\\oracle\\oradata\\practice";
/** 数据字典路径 */
public static String DATA_DICTIONARY = "D:\\oracle\\oradata\\practice\\LOGMNR";
}
2.2.2 SyncTask.java
在该类中有两个方法,第一个方法为 createDictionary,做用为生成数据字典文件,另一
个是startLogmur,该方法是 LogMiner分析同步方法。
/**
* <p>方法名称: createDictionary|描述: 调用logminer
/**
* <p>方法名称: startLogmur|描述:启动
生成数据字典文件</p>
* @param sourceConn 源数据库链接
* @throws Exception 异常信息
*/
public void createDictionary(Connection sourceConn) throws Exception{
String createDictSql = "BEGIN dbms_logmnr_d.build(dictionary_filename =>
'dictionary.ora', dictionary_location =>'"+Constants.DATA_DICTIONARY+"'); END;";
CallableStatement callableStatement = sourceConn.prepareCall(createDictSql);
callableStatement.execute();
}
logminer分析 </p>
* @throws Exception
*/
public void startLogmur() throws Exception{
第 5 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
Connection sourceConn = null;
Connection targetConn = null;
try {
ResultSet resultSet = null;
// 获取源数据库链接
sourceConn = DataBase.getSourceDataBase();
Statement statement = sourceConn.createStatement();
// 添加全部日志文件,本代码仅分析联机日志
StringBuffer sbSQL = new StringBuffer();
sbSQL.append(" BEGIN");
sbSQL.append("
dbms_logmnr.add_logfile(logfilename=>'"+Constants.LOG_PATH+"\\REDO01.LOG',
options=>dbms_logmnr.NEW);");
sbSQL.append("
dbms_logmnr.add_logfile(logfilename=>'"+Constants.LOG_PATH+"\\REDO02.LOG',
options=>dbms_logmnr.ADDFILE);");
sbSQL.append("
dbms_logmnr.add_logfile(logfilename=>'"+Constants.LOG_PATH+"\\REDO03.LOG',
options=>dbms_logmnr.ADDFILE);");
sbSQL.append(" END;");
CallableStatement callableStatement = sourceConn.prepareCall(sbSQL+"");
callableStatement.execute();
// 打印获分析日志文件信息
resultSet = statement.executeQuery("SELECT db_name, thread_sqn, filename FROM
v$logmnr_logs");
while(resultSet.next()){
System.out.println("已添加日志文件==>"+resultSet.getObject(3));
}
System.out.println("开始分析日志文件,起始scn号:"+Constants.LAST_SCN);
callableStatement = sourceConn.prepareCall("BEGIN
dbms_logmnr.start_logmnr(startScn=>'"+Constants.LAST_SCN+"',dictfilename=>'"+Consta
nts.DATA_DICTIONARY+"\\dictionary.ora',OPTIONS
=>DBMS_LOGMNR.COMMITTED_DATA_ONLY+dbms_logmnr.NO_ROWID_IN_STMT);END;");
callableStatement.execute();
System.out.println("完成分析日志文件");
// 查询获取分析结果
System.out.println("查询分析结果");
resultSet = statement.executeQuery("SELECT
scn,operation,timestamp,status,sql_redo FROM v$logmnr_contents WHERE
seg_owner='"+Constants.SOURCE_CLIENT_USERNAME+"' AND seg_type_name='TABLE' AND
operation !='SELECT_FOR_UPDATE'");
第 6 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
// 链接到目标数据库,在目标数据库执行redo语句
targetConn = DataBase.getTargetDataBase();
Statement targetStatement = targetConn.createStatement();
String lastScn = Constants.LAST_SCN;
String operation = null;
String sql = null;
boolean isCreateDictionary = false;
while(resultSet.next()){
lastScn = resultSet.getObject(1)+"";
if( lastScn.equals(Constants.LAST_SCN) ){
continue;
}
operation = resultSet.getObject(2)+"";
if( "DDL".equalsIgnoreCase(operation) ){
isCreateDictionary = true;
}
sql = resultSet.getObject(5)+"";
// 替换用户
sql = sql.replace("\""+Constants.SOURCE_CLIENT_USERNAME+"\".", "");
System.out.println("scn="+lastScn+",自动执行sql=="+sql+"");
try {
targetStatement.executeUpdate(sql.substring(0, sql.length()-1));
} catch (Exception e) {
System.out.println("测试一下,已经执行过了");
}
}
// 更新scn
Constants.LAST_SCN = (Integer.parseInt(lastScn))+"";
// DDL发生变化,更新数据字典
if( isCreateDictionary ){
System.out.println("DDL发生变化,更新数据字典");
createDictionary(sourceConn);
System.out.println("完成更新数据字典");
isCreateDictionary = false;
}
System.out.println("完成一个工做单元");
}
finally{ 第 7 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
if( null != sourceConn ){
sourceConn.close();
}
if( null != targetConn ){
targetConn.close();
}
sourceConn = null;
targetConn = null;
}
}
3 运行结果
3.1 源数据库操做
一、建立 AAAAA表,并插入数据
二、建立EMP1 表 第 8 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
3.2 运行 Demo
在控制台中输出以下日志
3.3 目标数据库结果
建立 AAAAA和EMP1 表,并在AAAAA插入了数据 第 9 页 共 9 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan
转:http://files.cnblogs.com/files/shishanyuan/3.%E4%BD%BF%E7%94%A8OracleLogminer%E5%90%8C%E6%AD%A5Demo.pdf 数据库