数据同步可能会经常遇到,实现的方法有利用触发器和高级复制功能以及第三方工具等多种
方式。
实现这三种方式的前提是要首先建立数据库链接。
具体的实现方法如下:
一,用触发器方式实现同步主要适用与要同步的表较少的情况,如果表很多,会导致系统运
行过慢。其工作的原理在于在对源表进行
insert,update,delete操作时,连动对需要同步的数据库中的相应的表进行insert,update和d
elete操作。
实现的具体脚本如下:
CREATE OR REPLACE TRIGGER "ZHGS"(触发器所属用户).DCTRI_BMS_SETTLE_ACCOUNT(触发器
名称)
AFTER INSERT OR UPDATE OR DELETE ON BMS_SETTLE_ACCOUNT(在该表上操作引发触发器
) FOR EACH ROW(每行的改动都触发)
DECLARE
m_Wheres VARCHAR2(200);
m_nouse number;
m_dataid number;
BEGIN
IF INSERTING THEN
DBCOPY2_PK.PF_BEGIN_INSERT('BMS_SETTLE_ACCOUNT','USEDAY =
GETSDATE(:NEW.USEDAY)');
IF :NEW.USEDAY IS NOT NULL THEN
DBCOPY2_PK.PF_WHEN_INSERT_DATE('USEDAY',:NEW.USEDAY);
END IF;
IF :NEW.USESTATUS IS NOT NULL THEN
DBCOPY2_PK.PF_WHEN_INSERT_NUMBER('USESTATUS',:NEW.USESTATUS);
END IF;
DBCOPY2_PK.PF_END_INSERT;
RETURN;
END IF;
IF UPDATING THEN
m_wheres:= 'USEDAY = GETSDATE(:OLD.USEDAY);
DBCOPY2_PK.PF_BEGIN_UPDATE('BMS_SETTLE_ACCOUNT',m_wheres);
IF
NVL(:NEW.USEDAY,TO_DATE('1900/1/1','YYYY/MM/DD'))<>NVL(:OLD.USEDAY,TO_DATE('1900/1/
1','YYYY/MM/DD')) THEN
DBCOPY2_PK.PF_WHEN_UPDATE_DATE('USEDAY',:NEW.USEDAY);
END IF;
IF NVL(:NEW.USESTATUS,0)<>NVL(:OLD.USESTATUS,0) THEN
DBCOPY2_PK.PF_WHEN_UPDATE_NUMBER('USESTATUS',:NEW.USESTATUS);
END IF;
DBCOPY2_PK.PF_END_UPDATE;
RETURN;
END IF;
IF DELETING THEN
m_wheres:= 'USEDAY = GETSDATE(:OLD.USEDAY);
DBCOPY2_PK.PF_BEGIN_DELETE('BMS_SETTLE_ACCOUNT',m_wheres);
m_dataid := DBCOPY2_PK.PF_END_DELETE;
IF m_dataid >0 THEN
INSERT INTO DCR_BMS_SETTLE_ACCOUNT ("USEDAY",
"USESTATUS",DC_DATAID) VALUES (:OLD.USEDAY,
:OLD.USESTATUS,TO_CHAR(m_dataid));
END IF;
RETURN;
END IF;
END;
二,用高级复制功能的方法
orcle 的复制机制主要是通过实体化视图(materialized view)实现的。实体化视图能够把从一
个或多个基表或视图上查询出来的结果另外保存到一个工作区对象去。
高级复制功能有三种方式:
read-only materialized view
updatable materialized view
N-way multimaster replication(n路多主控方复制)
假设有两个数据库:db1、db2,主为db1,从为db2
1,建用户(专门管理复制的repadmin用户),赋权限(??)
SQL>create user repadmin identified by repadmin default tablespace users temporary
tablespace temp;
SQL>execute dbms_defer_sys.register_propagator('repadmin');
SQL>grant execute any procedure to repadmin;
SQL>execute dbms_repcat_admin.grant_admin_any_repgroup('repadmin'); (管理复制组)
SQL>grant comment any table to repadmin;
SQL>grant lock any table to repadmin;
db1,db2均需要上面的环节
2, 在数据库复制的用户repadmin下创建私有的数据库链接。
db1,db2均需要上面的环节
3, 创建或选择实现数据库复制的用户和对象,给用户赋权,数据库对象必须有主关键字。
假设我们用ORACLE里举例用的scott用户,dept表。
①、用internal身份登录db1数据库,创建scott用户并赋权
SQL>create user scott identified by tiger default tablespace users temporary
tablespace temp;
SQL>grant connect, resource to scott;
SQL>grant execute on sys.dbms_defer to scott;
②、用scott身份登录db1数据库,创建表dept
SQL>create table dept
(deptno number(2) primary key,
dname varchar2(14),
loc varchar2(13) );
③、如果数据库对象没有主关键字,可以运行以下SQL命令添加:
SQL>alter table dept add (constraint dept_deptno_pk primary key (deptno));
④、在db1数据库scott用户下创建主关键字的序列号,范围避免和db2的冲突。
SQL> create sequence dept_no increment by 1 start with 1 maxvalue 44 cycle nocache;
(说明:maxvalue 44可以根据应用程序及表结构主关键字定义的位数需要而定)
⑤、在db1数据库scott用户下插入初始化数据
SQL>insert into dept values (dept_no.nextval,'accounting','new york');
SQL>insert into dept values (dept_no.nextval,'research','dallas');
SQL>commit;
⑥、在db2数据库那边同样运行以上①,②,③
⑦、在db2数据库scott用户下创建主关键字的序列号,范围避免和db1的冲突。
SQL> create sequence dept_no increment by 1 start with 45 maxvalue 99 cycle
nocache;
⑧、在db2数据库scott用户下插入初始化数据
SQL>insert into dept values (dept_no.nextval,'sales','chicago');
SQL>insert into dept values (dept_no.nextval,'operations','boston');
SQL>commit;
4,创建要复制的组scott_mg,加入数据库对象,产生对象的复制支持
①、用repadmin身份登录db1数据库,创建主复制组scott_mg
SQL> execute dbms_repcat.create_master_repgroup('scott_mg');
说明:scott_mg组名可以根据用户的需求自由命名。
②、在复制组scott_mg里加入数据库对象
SQL>execute dbms_repcat.create_master_repobject(sname=>'scott',oname=>'dept',
type=>'table',use_existing_object=>true,gname=>'scott_mg');
参数说明:
sname 实现数据库复制的用户名称
oname 实现数据库复制的数据库对象名称
(表名长度在27个字节内,程序包名长度在24个字节内)
type 实现数据库复制的数据库对象类别
(支持的类别:表,索引,同义词,触发器,视图,过程,函数,程序包,程序包体)
use_existing_object true表示用主复制节点已经存在的数据库对象
gname 主复制组名
③、对数据库对象产生复制支持
SQL>execute dbms_repcat.generate_replication_support('scott','dept','table');
(说明:产生支持scott用户下dept表复制的数据库触发器和程序包)
④、确认复制的组和对象已经加入数据库的数据字典
SQL>select gname, master, status from dba_repgroup;
SQL>select * from dba_repobject;
5,创建主复制节点 (关键)
①、用repadmin身份登录db1数据库,创建主复制节点
SQL>execute dbms_repcat.add_master_database
(gname=>'scott_mg',master=>'db2',use_existing_objects=>true, copy_rows=>false,
propagation_mode => 'asynchronous');
参数说明:
gname 主复制组名
master 加入主复制节点的另一个数据库
use_existing_object true表示用主复制节点已经存在的数据库对象
copy_rows false表示第一次开始复制时不用和主复制节点保持一致
propagation_mode 异步地执行
②、确认复制的任务队列已经加入数据库的数据字典
SQL>select * from user_jobs;
6、使同步组的状态由停顿(quiesced)改为正常(normal)
①、用repadmin身份登录db1数据库,运行以下命令
SQL> execute dbms_repcat.resume_master_activity('scott_mg',false);
②、确认同步组的状态为正常(normal)
SQL> select gname, master, status from dba_repgroup;
③、如果这个①命令不能使同步组的状态为正常(normal),可能有一些停顿的复制,运行以下
命令再试试(建议在紧急的时候才用):
SQL> execute dbms_repcat.resume_master_activity('scott_mg',true);
7,创建复制数据库的时间表
①、用repadmin身份登录db1数据库,运行以下命令
SQL>begin
dbms_defer_sys.schedule_push (
destination => 'db2',
interval => 'sysdate + 10/1440',
next_date => sysdate);
end;
/
SQL>begin
dbms_defer_sys.schedule_purge (
next_date => sysdate,
interval => 'sysdate + 10/1440',
delay_seconds => 0,
rollback_segment => '');
end;
/
②、用repadmin身份登录db2数据库,运行以下命令
SQL>begin
dbms_defer_sys.schedule_push (
destination => ' db1 ',
interval => 'sysdate + 10 / 1440',
next_date => sysdate);
end;
/
SQL>begin
dbms_defer_sys.schedule_purge (
next_date => sysdate,
interval => 'sysdate + 10/1440',
delay_seconds => 0,
rollback_segment => '');
end;
/
8,添加或修改两边数据库的记录,跟踪复制过程
如果你想立刻看到添加或修改后数据库的记录的变化,可以在两边repadmin用户下找到push的j
ob_number,然后运行:
SQL>exec dbms_job.run(job_number);
三,第三种工具的方式略去
你可以使用这个链接引用该篇文章 http://publishblog.blogchina.com/blog/tb.b?diaryID=2172578
| 拒绝雾里看花 高清晰屏幕手机推荐 | $relatedDiary.author |
| 拒绝雾里看花 高清晰屏幕手机推荐 | $relatedDiary.author |
| 努力着 | $relatedDiary.author |
| 漂亮的风光系列壁纸预览 | $relatedDiary.author |
| 通知:内部通讯录今日发布 | $relatedDiary.author |