发布一个用于Oracle数据库间数据复制的组件-OraSyner

     相信现在很多Application在使用db的时候,仍采用master-slave的方式,因为这种方式最贴近现实,开始可能只需要一台db server,可随着数据量的增加,一台会不堪重负,此时我们必须增加server,来应付日益增长的data,而我们在开发程序的时候,可能并没有想到系统日后要面临这样的分布式数据库系统,此时最好的解决方案就是master-slave,这样系统就可以不做任何的更新了。在工作中,我开发了一个用于同步master-slave之间数据的组件,他包括以下功能:

  1. 能够同步master和slave的数据
  2. 在同步数据的时候,能够记录运行过程

   

    他的特点是一个通用的组件,他通过配置文件来设置master和slave库,并且通过配置来设置要数据同步的数据表,当有新的数据表需要同步的时候,我们只需要在配置中增加一项就能解决问题。这个配置文件,名称为:OraSyner.cfg,将它放置在程序运行的目录里面。OraSyner.cfg中格式如下:

<?xml version="1.0" encoding="utf-8" ?>
<cfgs>
    
<servers>
        
<master>Password=321;User ID=username;Data Source=masterdb</master>
        
<slave>Password=123;User ID=username;Data Source=slavedb</slave>
    
</servers>
    
<syntables>
        
<table name="tablename">
            
<key>key1</key>
            
<key>    key2</key>
        
</table>
    
</syntables>
</cfgs>

 

节点名称

使用状态

节点说明

cfgs

在整个配置文件中有且只有一个

配置文件的根节点

servers

在整个配置文件中有且只有一个

用于声明master-salve服务器信息的根节点

master

在一个server中有且只有一个

Master db的连接字符串

slave

在一个server中有且只有一个

Salve db 的连接字符串

syntables

在整个配置文件中有且只有一个

用于声明待同步的数据表信息的根节点

table

在syntables中0个或者多个

用于声明待同步数据表信息的节点

Table[@name]

在table节点中有且只有一个的属性

用于指示同步数据表的名称

key

在一个table节点中1个或者多个

用于指示待同步数据表的行标志字段

该组件的特点:

  1. 通俗易用,扩展性强,搞明白上面的配置说明就万事大吉
  2. 能适用于任何环境之下,比如master在内网,而slave在外网,或者slave在内网,而master在外网,只要运行该组件的主机能连接到master和slave就可以。

该组件的工作原理:

通过读取配置文件,将要同步的数据表数据读取出来放到组件的DataSet中,然后针对每个表,先在master中获取表字典,然后根据配置中的行标志字段,生成用于同步slave的语句,主要采用oracle中的

 MERGE INTO 
 USING  
ON
 
 
WHEN MATCHED then

 
WHEN NOT MATCHED THEN


语句来实现同步功能,也就是有就更新,没有则插入,而一条条的 比对,性能会相对比较慢,所以先在slave中创建临时表,将数据插入到该临时表,然后一次性merge into.测试后,发现比一条条的快20倍左右。

本组件的适用范围:

  1. 发布/订阅不太方便的时候
  2. 数据量不宜太大,太大会搞死人的,比如上百万,上千万 ,我测试了下,几万的数据在几秒内还是能搞定的。再大了本组件就没戏了
  3. 临时 充当数据同步工具(其实我开发这个就是为了这个目的)

使用办法:

每次同步操作之需要调用Executor对象的Execute()方法即可,你可以将它加到作业调度软件中,定时的执行。
注意:产生的log信息会在程序运行的目录里面的log文件夹中按日期创建类似yyyyMmdd这样格式的文件夹。而如果想输出比较详尽的log信息,在.config中文件的<appSetting>中添加<add key="LogLevel" value="2"/>是必须的,value改为1,它只记录错误和提示信息,为0,只记录错误,为2记录错误,提示和调试信息。

组件项目文件:
/Files/jillzhang/OraSyner.rar 
 

 

作者:jillzhang
出处:http://jillzhang.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2008-01-20 01:41 Robin Zhang 阅读(2756) 评论(30)  编辑 收藏 网摘 所属分类: 组件开发

  回复  引用  查看    
#1楼2008-01-20 02:30 | Jeffrey Zhao      
是轮询的吗?那么延迟地如何呢?
  回复  引用  查看    
#2楼2008-01-20 03:30 | ξ箫音ξ      
这个确实不错,不过目前比较需要Microsoft SQL Server Compact 3.5与服务器端Sql2005的同步。
  回复  引用  查看    
#3楼[楼主]2008-01-20 08:52 | jillzhang      
@Jeffrey Zhao
我用的环境是轮询,也可以使用触发器来触发,不过性能太差
好像订阅/发布也是轮询地吧 ?
master-slave模式上可轮询的情况还是蛮多的

  回复  引用  查看    
#4楼[楼主]2008-01-20 08:55 | jillzhang      
@ξ箫音ξ
sql不支持merge语句,做起来性能更差

  回复  引用  查看    
#5楼2008-01-20 11:07 | ξ箫音ξ      
--引用--------------------------------------------------
jillzhang: @ξ箫音ξ
sql不支持merge语句,做起来性能更差

--------------------------------------------------------
数据库的同步,一般是采用轮询的,订阅/发布的方式;有的时候的时候,客户端数据程序需要与服务器SQL2005实现双向同步,让客户安装SQL2005不现实,所以采用Microsoft SQL Server Compact 3.5,RDA进行数据处理。

  回复  引用    
#6楼2008-01-20 11:59 | 路千里[未注册用户]
大数据表完全可以分区嘛
  回复  引用  查看    
#7楼[楼主]2008-01-20 12:35 | jillzhang      
@路千里
分区明显需要前期系统支持,不管是横分,还是纵分

  回复  引用  查看    
#8楼[楼主]2008-01-20 12:54 | jillzhang      
@ξ箫音ξ
其实sql也是可以的,只不过最好是sql 2005作为master,而compact作为slave,用if exists else也能解决,不过要一条条来,比较浪费性能

  回复  引用    
#9楼2008-01-21 08:37 | m[未注册用户]
ξ箫音ξ
或许可以看看Microsoft Sync Framework

  回复  引用  查看    
#10楼[楼主]2008-01-21 09:11 | jillzhang      
@m
嘻嘻,我先看看

  回复  引用    
#11楼2008-01-21 09:17 | m[未注册用户]
@jillzhang
谢谢你的分享,我最近也在做分布式系统数据库的同步(ORACLE),查找了很多资料,包括advanced replication,snapshot,oracle change data capture这些oracle自带的同步工具和方法,但感觉这些东西的局限性太大,不好控制,正好看到了您的组件,马上下载过来学习,感觉对我的帮助太大了,谢谢,呵呵

  回复  引用    
#12楼2008-01-21 09:22 | m[未注册用户]
Microsoft Sync Framework只是一个beta版,正式的还没出,同时目前只提供SQL SERVER CE 到SQL SERVER 2008的同步已经文件的同步,要做到其他库的同步,需要自己写Provider,当然,这套框架推出的主要目的好像是提供移动设备和PC的同步
  回复  引用  查看    
#13楼[楼主]2008-01-21 09:24 | jillzhang      
@m
安装了,还没来得及看呢
一会体验一下

  回复  引用    
#14楼2008-01-21 09:41 | memphis[未注册用户]
我有一个自己写的数据库同步的程序,支持异构数据库的增量同步,实践下来非常好用且简单。我使用的模式是同步采用C/S方式,也就是说有一个同步的服务器程序部署在MASTER数据库上,多个需要同步的slaver数据库服务器上部署同步组件程序,协议采用http。
  回复  引用  查看    
#15楼[楼主]2008-01-21 10:07 | jillzhang      
@memphis
请问你的能实现两边同步更新么?
增量的做起来就简单多了

  回复  引用    
#16楼2008-01-22 11:56 | m[未注册用户]
@jillzhang
Hi Jillzhang,今天用你的组件发现了一个问题,那就是如果Slave数据库是oracle 9i的话,同步的时候会出现“ora-00905:缺少关键字”的错误,导致不能同步成功。
经查,发现是那个"Merge Into"语句的问题,原来在oracle 9i中merge语句中on所包含的条件在后面的update中不能再使用,即
应将
MERGE INTO Test_MasterTable c
USING Test_MasterTabletemp cu ON ( c.sid = cu.sid )
WHEN MATCHED Then
update set c.sname = cu.sname , c.ADDRESS = cu.ADDRESS where c.sid=cu.sid
WHEN NOT MATCHED Then
insert values (cu.sid ,cu.sname ,cu.ADDRESS )

改成

MERGE INTO Test_MasterTable c
USING Test_MasterTabletpjz cu ON ( c.sid = cu.sid )
WHEN MATCHED Then
update set c.sname = cu.sname , c.ADDRESS = cu.ADDRESS
WHEN NOT MATCHED Then
insert values (cu.sid ,cu.sname ,cu.ADDRESS )

如果要同步9i的数据表,须在update中去掉那个c.sid = cu.sid条件,这样就不会出现“缺少关键字”的错误。

经测试,9i和10g中去掉update中的那个c.sid = cu.sid条件并不影响同步的效果。

  回复  引用    
#17楼2008-01-22 12:01 | m[未注册用户]
@jillzhang

还有一个问题想问你,你做这个东东是作为局域网内2个oracle库之间的同步工具吧?

  回复  引用  查看    
#18楼[楼主]2008-01-22 12:08 | jillzhang      
两个Oracle Server,可在不同网路中
  回复  引用  查看    
#19楼[楼主]2008-01-22 15:31 | jillzhang      
@m
刚才没注意你的留言,我对Oracle不是特别熟悉,我们目前的是10i,也没到9i上测试,多谢你的提醒和更正。

  回复  引用    
#20楼2008-01-22 20:34 | m[未注册用户]
@ jillzhang
呵呵,我也只是在用你这个组件才发现这个问题的,要感谢的还是你,我接下来的一个项目就打算采用您的这个方法来实现数据同步。

  回复  引用  查看    
#21楼[楼主]2008-01-22 21:21 | jillzhang      
@m
您在使用的时候,有什么bug麻烦您也发给我一下,我对此组件也好有个更新和维护,先谢了

  回复  引用    
#22楼2008-01-23 23:21 | m[未注册用户]
@jillzhang
没有问题

  回复  引用    
#23楼2008-01-25 15:56 | zbh[未注册用户]
使用MicrosoftOLEDBProviderForORACLE链接ORACLE

http://user.qzone.qq.com/53395741/blog/1199848555

  回复  引用  查看    
#24楼[楼主]2008-01-25 16:05 | jillzhang      
@zbh
能让外网订阅内网么?

  回复  引用  查看    
#25楼2008-09-25 22:37 | 张冰      
如果主服务器有数据删除,该如何些呢?
  回复  引用  查看    
#26楼2008-10-15 19:20 | 张冰      
我在你组件的基础上做了些改进。请多提些意见。
  回复  引用  查看    
#27楼[楼主]2008-10-15 20:18 | jillzhang      
@张冰
能不能将您的改进发给我一下

  回复  引用    
#28楼2008-11-10 12:09 | compiere[未注册用户]
各位可否告之,这个文件怎么在windows内执行,没有exe,com,bat等.
不甚感谢!




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1045934




相关文章:

相关链接: