日期:2014-05-16  浏览次数:20435 次

使用dblink快照功能,实现远程数据库的同步

-------------- 检查两台oracle服务器可以建立dblink的条件。------------------
--1.命令行远程登陆:sqlplus db_qb/pw123456@172.16.16.15:1521/orcl;
--2.查看Global_name参数是true还是False,该参数为true时,你在本地Oracle建立的DBLINK的名称必须和远程的Global_name一致才行
? sql> show parameter global_name;
--3.如何返回数据库的GLOBAL_NAME?
? SELECT * FROM GLOBAL_NAME;
--4.查看远程数据徊是否支持高级复制功能,通过查看v$option视图的中Advanced replication属性,如果为True,那么就是支持,否则就是不支持。在两个数据库中都是检查是否支持才行。
? select * from v$option where PARAMETER='Advanced replication';-- PARAMETER like 'Ad%'就可以;
-------------- 检查两台oracle服务器可以建立dblink的条件。------------------END
?

-----------------创建DBLINK--------------------------------


--select * from test
--1.在本地数据库上,创建dblink
--drop public database link mydblink;
Create public DATABASE LINK mydblink CONNECT TO zddxgltest IDENTIFIED BY PW123456 USING '172.16.17.7:1521/orcl';

--2.在本地数据库上,测试dblink
select * from test_175@mydblink
--3.在远程数据库上,创建要同步表的快照日志
--drop snapshot log on test_175;
Create snapshot log on test_175;
--4.在本地数据库创建目的数据库上目标表(test_175)的快照
--drop snapshot test_175_log
Create snapshot test_175_log as select * from test_175@mydblink
--???? 4.2最好能按照rowid来建立快照:(有问题,提示)
--???? create? snapshot test_175_log refresh fast with rowid start with sysdate next sysdate+30/(24*60*60) as select * from test_175@mydblink;
--5.在本地数据库设置快照刷新时间(只能选择一种刷新方式,推荐使用快速刷新,这样才可以用触发器双向同步)快速刷新
--5.1 每隔三十秒刷新一次 立即执行
--Alter snapshot test_175_log refresh fast Start with sysdate next sysdate+30/(24*60*60) with primary key;
--5.2 5秒后首次执行,每隔5秒刷新一次
Alter snapshot test_175_log refresh complete Start with sysdate+5/(24*60*60) next sysdate+5/(24*60*60);--设置5秒重新扫描原始表(实际是10秒)
--说明:快照每隔10秒将所有数据全部删除delete然后在全部添加inset,所以间隔时间越小系统消耗会越大。
/*
手动启动:
begin
dbms_refresh.refresh('test_175_log');
end;
*/
--7.测试同步结果
select * from test_175_log


-----------------创建DBLINK--------------------------------END

?


-----------------触发器最终实现数据同步--------------------------------
select * from user_triggers
--时间累加。
--select sysdate,sysdate+30/(24*60*60) from dual
--ORACLE查出表所有的触发器,表明必须全是大写
select t.trigger_name,t.* from all_triggers t where table_name='TEST_175_LOG';
--6.触发器实现数据同步。
--6.1 插入触发器。
--drop? trigger TEST_BACK_TRIGGER
--3.建立快照的触发器(快照每隔10秒将所有数据全部删除delete然后在全部添加inset,所以日志会很多很大,可以考虑不记录日志。)
------------------------------
--开启屏幕监听:
--sql>set serveroutput on;
CREATE OR REPLACE TRIGGER test_log_trigger
AFTER DELETE OR INSERT OR UPDATE ON test_175_log for each row -- for each row是为了使用:new和old
DECLARE
v_type VARCHAR2(15);
BEGIN
IF INSERTING THEN
? v_type := 'INSERT '||:new.T_ID;--oracle添加链接字符串使用||
? DBMS_OUTPUT.PUT_LINE('记录'||:new.T_ID||'已经成功插入,并已记录到日志');--添加 只有new
? INSERT INTO TEST_BACK VALUES(:new.T_ID,:new.T_NAME,:new.T_AGE,:new.T_SEX);--同步表。
ELSIF UPDATING THEN
? v_type := 'UPDATE '||:old.T_ID;
? DBMS_OUTPUT.PUT_LINE('记录'||:old.T_ID||'已经成功更新,并已记录到日志');--更新有new和old
? UPDATE TEST_BACK T SET T.T_NAME = :new.T_NAME,T.T_AGE = :new.T_AGE,T.T_SEX =:new.T_SEX where T.T_ID = :old.T_ID;--注意末尾的;号
ELSIF DELETING THEN
? v_type := 'DELETE '||:old.T_ID;
? DBMS_OUTPUT.PUT_LINE('记录'||:old.T_ID||'已经成功删除,并已记录到日志');--删除只有old
? DELETE FROM TEST_BACK T where T.T_ID = :old.T_ID;--注意末尾的;号
END IF;
-- my_pro(v_type);--记录日志。
END;

------------------------------


----------------------------
--2.建存储过程(注意一定要加上PRAGMA AUTONOMOUS_TRANSACTION;让这个存储过程有自治的事务控制,不然会影响A的事务控制)
----------------------------
create or replace procedure my_pro(v_type varchar2)
as
PRAGMA AUTONOMOUS_TRANSACTION;
begin
INSERT INTO LOG_TEST VALUES(user,v_type,TO_CHAR(sysdate,'yyyy-mm-dd hh24:mi:ss'));--操作日志。
commit;
end;
---------------------------

--最后我们在远程数据库中输入以下测试语句:
INSERT INTO test_175 VALUES(34,'zhao',22,'M');
UPDATE test_175 SET t_name = '3ddd0' WHERE t_id = 34;