目前市面上有不少Oracle databasae数据库同步的软件,普遍分两类:Oracle原厂的(OGG)、开源免费的(SymmetricDS)。原厂的原理是读取redo log和archive log,SDS主要是通过Trigger做同步。实际测试的结果,感觉很臃肿,OGG很贵,其实我们是可以通过archive log做同步的(但是建议,要资深的DBA才能做,因为log miner是需要DBA权限的。作者在世界500强跨国企业当DBA超过10年)
实验环境:
Source DB:
-- RHEL5.8 X64 OS
-- Oracle11g SE1 DB
Target DB:
-- CENTOS6.5 X64 OS
-- Oracle11g SE1 DB
使用的工具:
Python2.6、Bshell(Linux自带), Oracle Client(Oracle11g 自带)
比较难的点:
-- 利用log miner读取log
-- 利用Linux的ls, seq, awk定位最近产生的log(这个难不倒大家吧)
-- 利用Python把SQL, Shell结合在一起,做到real-time
首先,log miner需要先安装,网上很多范例,就不多说了。安装完成后,利用下面的SQL语句,就可以找到相对应的SQL。产生完SQL就直接在target DB执行。
SQL>
alter session set NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"; -- 如果不设定,就只能看到日期看不到时间
execute dbms_logmnr.add_logfile(LogFileName=>'/home/hadoop/ora11g/dbs/arch/1_204_897823121.dbf', options=>dbms_logmnr.new); -- 需要分析的log
execute dbms_logmnr.start_logmnr(Options=>dbms_logmnr.DICT_FROM_ONLINE_CATALOG+DBMS_LOGMNR.COMMITTED_DATA_ONLY+DBMS_LOGMNR.NO_ROWID_IN_STMT); -- 读取在线的字典,只有commit的语句才读出来,不要ROWID
set feedback off
set heading off
spool spool.tmp
SELECT sql_redo FROM v$logmnr_contents where seg_name ='TEST'; -- 需要找什么样的table就看自己了条件自己把握。
execute dbms_logmnr.end_logmnr;
spool off
exit;
实验内容:通过对test.test表格的修改,看log miner是否可以从log中找到相关的SQL语句:
Table test.test的内容:
SQL> select * from test.test;
ID COL1
---------- --------------------------------
1 a
2 aa
3 aaa
1. 增加个字段:newcol
PL/SQL procedure successfully completed.
ALTER TABLE TEST.TEST ADD (newcol VARCHAR2(32 BYTE)); 《== 这个是从log miner捞到的数据
2. 插入条record
PL/SQL procedure successfully completed.
insert into "TEST"."TEST"("ID","COL1","NEWCOL" values ('4','newa',NULL); 《== 这个是从log miner捞到的数据
3. truncate table数据
PL/SQL procedure successfully completed.
TRUNCATE TABLE TEST.TEST drop storage; 《== 这个是从log miner捞到的数据
4. delete table
PL/SQL procedure successfully completed.
DROP TABLE TEST.TEST CASCADE CONSTRAINTS PURGE; 《== 这个是从log miner捞到的数据
以上基本的操作,都可以完全做出来。当然,其他DDL和数据类型,就要按照情况测试了。当然,这个是基本功,需要自动化运维的话,还需要更多的知识,这里是利用Python做的,Linux+Python+Oracle,可以做到自动化分析archive log,自动化apply to target DB。后续也可以和Hbase结合,或者与Hadoop结合。这样就可以基本上做到读写分离了。也完全可以读取redo log,不过,自己试试看吧。挺好玩的。
5. 支持CLOB
PL/SQL procedure successfully completed.
insert into "TEST"."TEST"("ID","CLOB") values ('4',EMPTY_CLOB());
DECLARE
loc_c CLOB;
buf_c VARCHAR2(6156);
loc_b BLOB;
buf_b RAW(6156);
loc_nc NCLOB;
buf_nc NVARCHAR2(6156);
BEGIN
select "CLOB" into loc_c from "TEST"."TEST" where "ID" = '4' for update;
dbms_lob.trim(loc_c, 0);
END;
update "TEST"."TEST" set "CLOB" = 'Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, Hello, Yes, ' where "ID" = '4';