- 浏览: 108642 次
- 性别:
- 来自: 昆明
文章分类
- 全部博客 (151)
- 120D02 (5)
- 直升机 (1)
- 我的技术资料收集 (82)
- 的技术资料收集 (4)
- .NET Solution (2)
- ASP.NET (1)
- Linq to sql (1)
- 数据库技术(MS SQL) (2)
- 架构/设计 (1)
- 敏捷/持续集成 (1)
- C#.NET开发 (1)
- Matlab开发 (1)
- WinForm开发 (1)
- 开源技术 (1)
- jQuery (1)
- 我的博文 (4)
- js (2)
- android (2)
- 9. 读书笔记 (1)
- CSS3 (1)
- HTML5 (1)
- JavaScript (5)
- 移动开发 (2)
- 编程心得 (1)
- Linux操作系统 (1)
- (BI)商业智能 (1)
- IOS (1)
- Windows Phone (2)
- C# API (1)
- JQuery系列 (1)
- TFS (1)
- C# (2)
- ExtJs (1)
- .NET (1)
- Nginx (1)
- WCF学习笔记 (1)
- Computer Graphic (1)
- IT产品 (1)
- 工具分享 (1)
- MySelf (1)
- C#专栏 (1)
- 管理 (1)
- 基于Oracle Logminer数据同步 (1)
- 日常 (1)
- 实用工具 (1)
- 网页设计 (1)
- avalon (1)
- flash (1)
- DDD (1)
- 01 技术Android (1)
- WCF (1)
- selenium (1)
最新评论
-
464410531:
三国杀。。。。。。。。。。。。。。。。。。。。。。。。。。。。 ...
实用的职场宝典:不提拔你,就因为你只想把工作做好
使用Oracle Logminer同步Demo
1 Demo介绍
1.1 Demo设想
前面介绍了Oracle LogMiner配置使用以及使用LogMiner进行解析日志文件性能,在这篇文章中将利用LogMiner进行数据同步,实现从源目标数据库到目标数据库之间的数据同步。由于LogMiner支持的版本是8.1及以上,所以进行数据同步的Oracle数据库版本也必须是8.1及以上。
当然在本文中介绍的是LogMiner进行数据同步例子,也可以利用LogMiner进行数据审计、数据操作追踪等功能,由于这些从操作原理来说是一致,在本文不做讨论。
1.2 框架图
1.3 流程图
l 配置阶段
1、 控制端:指定源端、目标端数据库信息、LOGMINER同步时间等配置信息;
l 获取源端同步数据
2、 控制台:通过定时轮询的方式检测是否到达数据同步时间,如果是则进行数据同步,否则继续进行轮询;
3、 源数据库:定时加载数据库归档日志文件到动态表v$logmnr_contents中;
4、 源数据库:根据条件读取指定sql语句;
l 目标端数据入库
5、 源数据库:执行sql语句。
2 代码分析
2.1 目录及环境配置
在该Demo项目中需要引入Oracle JDBC驱动包,具体项目分为四个类:
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";
/** 源数据库配置 */
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>
* @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();
}
/**
* <p>方法名称: startLogmur|描述:启动logminer分析 </p>
* @throws Exception
*/
public void startLogmur() throws Exception{
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=>'"+Constants.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'");
// 连接到目标数据库,在目标数据库执行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{
if( null != sourceConn ){
sourceConn.close();
}
if( null != targetConn ){
targetConn.close();
}
sourceConn = null;
targetConn = null;
}
}
3 运行结果
3.1 源数据库操作
1、创建AAAAA表,并插入数据
2、创建EMP1表
3.2 运行Demo
在控制台中输出如下日志
3.3 目标数据库结果
创建AAAAA和EMP1表,并在AAAAA插入了数据
发表评论
-
Javascript:猜猜弹出的是啥?为啥? - 幸福框架
2013-06-28 13:33 426原帖地址:http://www.cnblogs.com/hap ... -
C#中WindowsForm常见控件的运用 -- - 李晓峰
2013-06-28 13:27 1742原帖地址:http://www.cnblogs.com/liy ... -
海量数据处理利器之Hash——在线邮件地址过滤 - MyDetail
2013-06-27 12:00 644原帖地址:http://www.cnblo ... -
ASP.NET MVC 4 for Visual Studio 2010 下载地址 - 张鸿伟
2013-06-27 11:48 749原帖地址:http://www.cnblogs.com/wei ... -
【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化 - r01cn
2013-06-26 11:00 918原帖地址:http://www.cnblogs.com/r01 ... -
[珠玑之椟]估算的应用与Little定律 - 五岳
2013-06-26 10:54 634原帖地址:http://www.cnblogs.com/wuy ... -
30行,金额转人民币大写的代码 - 史蒂芬.王
2013-06-26 10:42 1024原帖地址:http://www.cnblogs.com/ste ... -
从银行的钱荒看一个公司的团队建设 产品线过多最终导致最赚钱的项目面临破产 - James Li
2013-06-26 10:36 626原帖地址:http://www.cnblogs.com/Jam ... -
Windows 8 动手实验系列教程 实验6:设置和首选项 - zigzagPath
2013-06-25 13:39 532原帖地址:http://www.cnblogs.com/zig ... -
闲聊可穿戴设备 - shawn.xie
2013-06-25 13:33 612原帖地址:http://www.cnblo ... -
如何使用开源库,吐在VS2013发布之前,顺便介绍下VS2013的新特性"Bootstrap" - 量子计算机
2013-06-25 13:27 867原帖地址:http://www.cnblogs.com/DSh ... -
一步一步将自己的代码转换为观察者模式 - 文酱
2013-06-23 11:36 606原帖地址:http://www.cnblo ... -
iOS内存错误EXC_BAD_ACCESS的解决方法(message sent to deallocated instance) - VicStudio
2013-06-23 11:30 539原帖地址:http://www.cnblogs.com/vic ... -
记录asp.net在IE10下事件丢失排错经过 - Adming
2013-06-23 11:24 709原帖地址:http://www.cnblogs.com/wea ... -
记 FineUI 官方论坛所遭受的一次真实网络攻击!做一个像 ice 有道德的黑客! - 三生石上
2013-06-23 11:18 791原帖地址:http://www.cnblogs.com/san ... -
算法实践——数独的基本解法
2013-06-19 10:27 1446原帖地址:http://www.cnblogs.com/gre ... -
简单实现TCP下的大文件高效传输
2013-06-19 10:21 688原帖地址:http://www.cnblogs.com/sma ... -
avalon - 初步接触
2013-06-18 10:06 781原帖地址:http://www.cnblogs.com/aar ... -
Nginx学习笔记(一) Nginx架构
2013-06-18 09:59 523原帖地址:http://www.cnblogs.com/cod ... -
证书打印《二》
2013-06-17 10:47 528原帖地址:http://www.cnblogs.com/bin ...
相关推荐
超级简单的ORACLE LOGMINER使用简单步骤,一看就会。
本文介绍了使用 Oracle LogMiner 进行日志分析的方法,并强调了数据库版本、DB NAME 和生成的数据字典的 DBID 一致性问题的重要性。同时,本文也提供了使用 nid 工具修改 DB NAME 和 DBID 的方法,以便与日志来源库...
在使用 Logminer 进行分析之前,通常需要创建数据字典文件,尤其是在 Oracle 10g 及以后的版本,可以使用在线数据字典。数据字典对于正确解读日志中的操作至关重要,因为它将内部对象ID转换为可读的表名和列名。如果...
### 使用Oracle Logminer进行数据同步的关键知识点 #### 1. Oracle Logminer简介与应用场景 - **Oracle Logminer** 是Oracle数据库提供的一种工具,用于解析重做日志文件(Redo Log Files),从中提取出对数据库所...
Oracle LogMiner是Oracle数据库内置的一个实用工具,用于分析重做日志文件(redo logs),帮助DBA(数据库管理员)和开发人员理解数据库中的事务历史、数据更改以及系统活动。这个工具无需创建归档模式,就能对在线...
Oracle 日志分析工具 LogMiner 使用 Oracle 日志分析工具 LogMiner 是 Oracle 数据库中的一种功能强大且灵活的日志分析工具,它可以帮助数据库管理员、开发人员和用户快速地对数据库进行日志分析和问题诊断。下面是...
### Oracle日志管理logminer使用 #### 一、Oracle日志管理概述 Oracle数据库通过日志记录了所有对数据的更改操作,这对于确保数据的一致性和完整性至关重要。Oracle中的日志主要包括重做日志(Redo Logs)和归档...
### Oracle日志分析工具LogMiner使用详解 #### 一、概述 Oracle LogMiner是Oracle数据库提供的一个强大工具,用于分析重做日志文件,提取数据库中的更改记录(即SCN序列)。通过LogMiner,我们可以追踪并监控...
在这种情况下,Oracle提供的LogMiner工具成为一个经济实惠且实用的选择,它允许用户分析重做日志以获取数据库更改信息,从而实现数据同步。 LogMiner的基本原理是解析数据库的redo logs,这些日志记录了所有对...
Oracle Redo Log就像Oracle数据库的录像带,记录了数据库中的所有改变,Oracle Logminer工具可以有效地挖掘并且呈现出Redo Log中的事务变化,从而可以实现数据恢复、Oracle Redo Log机制的研究、数据库监控和审计、...
### Oracle 9i LogMiner工具使用说明 #### 一、LogMiner工具概述与用途 Oracle 9i LogMiner工具是一种强大的数据库审计和数据分析工具,主要用于追踪和分析数据库的变更活动。通过分析重做日志文件(Redo Log ...
在Oracle 9i及更高版本中,还可以使用FLASHBACK功能进行恢复,但LOGMINER在不支持或不适合使用FLASHBACK的情况下仍是一种选择。 LOGMINER由一系列PL/SQL包和动态视图构成,虽然没有图形用户界面,但可以通过SQL...
Oracle的日志分析工具LogMiner是Oracle数据库内置的一个强大功能,用于分析数据库的redo logs,以获取关于数据库操作的历史信息。LogMiner可以帮助DBA进行...正确配置和使用LogMiner是每个Oracle DBA必备的技能之一。
Oracle 10g LogMiner 是Oracle数据库的一个内置工具,用于分析数据库的重做日志文件,从而获取关于事务的历史信息、SQL语句及其影响的数据变化。LogMiner 提供了一个方便的方式来审计和理解数据库中发生的变化,而...