`

两相同方案数据库同步策略(快照)!

阅读更多

本实例已完全通过测试,单向,又向同步都可使用.

--名词说明:源——被同步的数据库 目的——要同步到的数据库

6步必须执行,6以后是一些辅助信息.

1、在源和目的数据库上创建要同步的表(所有表最好有主键约束,这样快照才可以快速刷新,可以利用imp工具恢复两个相同方案的数据库,保持表结构一致,以下举一表结构为实例)

drop table test_user;

create table test_user(id number(10) primary key,name varchar2(12),age number(3));

2、在目的数据库上,创建dblink

drop database link dblinkname;

Create DATABASE LINK dblinkname CONNECT TOusername IDENTIFIED BY password USING 'services_name';

--dblinkname dblink_name

--username username

--password password

--'services_name' 是远程数据库名

3、在目的数据库上,测试dblink

select * from test_user@dblinkname; //查询的是源数据库的表 select * from test_user;

4、在源数据库上,创建要同步表的快照日志

Create snapshot log on test_user;

5、在目的数据库上创建快照

Create snapshot sn_test_user as select * from test_user@dblink_orc92_182;

6、设置快照刷新时间(只能选择一种刷新方式,推荐使用快速刷新,这样才可以用触发器双向同步)

快速刷新

Alter snapshot sn_test_user refresh fast Start with sysdate next sysdate with primary key;

--oracle马上自动快速刷新,以后不停的刷新,只能在测试时使用.真实项目要正确权衡刷新时间.

完全刷新

Alter snapshot sn_test_user refresh complete Start with sysdate+30/24*60*60 next sysdate+30/24*60*60;

--oracle自动在30秒后进行第一次完全刷新,以后每隔30秒完全刷新一次

7、手动刷新快照,在没有自动刷新的情况下,可以手动刷新快照.

手动刷新方式1 begin dbms_refresh.refresh('sn_test_user'); end;

手动刷新方式2 EXEC DBMS_SNAPSHOT.REFRESH('sn_test_user','F'); //第一个参数是快照名,第二个参数 F 是快速刷新 C 是完全刷新.

8.修改会话时间格式

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

9.查看快照最后一次刷新时间

SELECT NAME,LAST_REFRESH FROM ALL_SNAPSHOT_REFRESH_TIMES;

10.查看快照下次执行时间

select last_date,next_date,what from user_jobs order by next_date;

11.打印调试信息

dbms_output.put_line('use '||'plsql');

12.如果你只想单向同步,那么在目的数据库创建以下触发器(当源数据库表改变时,目的数据库表跟着改变,但目的数据库表改变时,源数据库表不改变).

create or replace trigger TRI_test_user_AFR after insert or update or delete on sn_test_user for each row begin if deleting then delete from test_user where id=:old.id; end if; if inserting then insert into test_user(id,name) values(:new.id,:new.name); end if; if updating then update test_user set name=:new.name where id=:old.id; end if; end TRI_test_user_AFR;

13.如果你想双向同步,请在源数据库中执行前6,并在双方都创建以下触发器(当源数据库表改变时,目的数据库表跟着改变,目的数据库表改变时,源数据库表也改变)

CREATE OR REPLACE TRIGGER BST114.TRI_TEST_USER_AFR AFTER DELETE OR INSERT OR UPDATE ON BST114.SN_TEST_USER REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW declare tmp_id number(10):=-1; begin

dbms_output.put_line('begin'); if inserting then --select id into tmp_id from test_user where id=:new.id; for p in(select id from test_user where id=:new.id) loop tmp_id:=p.id; end loop; dbms_output.put_line(tmp_id||'===------------'); if (tmp_id=-1) then insert into test_user(id,name,age) values(:new.id,:new.name,:new.age); end if; end if; if updating then dbms_output.put_line('updated'); for p in(select name,age from test_user where id=:old.id) loop if (p.name!=:new.name) or (p.age!=:new.age) then update test_user set name=:new.name,age=:new.age where id=:old.id; end if; end loop; end if; if deleting then dbms_output.put_line('deleted'); delete from test_user where id=:old.id; end if; dbms_output.put_line('end'); end TRI_test_user_AFR;

--为防止双向同步触发器死循环,所以要在触发器中增加一些判断,阻止死循环.

以上同步原理

1.首先创建一个dblink,可以访问远程数据库

2.在本地创建一个快照,映射远程数据表,当远程数据表有变化时,会反应到快照中.

3.由于快照类似于视图表,所以在本地为快照创建一个触发器,当快照有变化时,会触发相应事件.

4.在触发器中写同步数据的代码.

:快照刷新时间参数说明

一天的秒数=24小时*60分钟*60

所以要想在30秒后刷新,参数应该这样写 sysdate+30/(24*60*60) 1分钟==sysdate+60/(24*60*60)

一天的分钟数=24小时*60分钟

一分钟也可以这样写 sysdate+1/(24*60)

30分钟==sysdate+30/(24*60)

60分钟==sysdate+60/(24*60)

以此类推

1小时==sysdate+1/24==sysdate+60/(24*60)

1==sysdate+1

一个月==sysdate+30

注:如果想实现全库所有表的同步,可以利用过程来完成创建快照、快照日志和触发器的功能.

第一步:

在源库中建立如下过程(用于创建快照日志):

CREATE OR REPLACE PROCEDURE PRO_WF_SNAPSHOST_LOG (TABLESPACE_NAME IN VARCHAR2) AS

CURSOR CUR_TABLE IS

SELECT TABLE_NAME FROM USER_TABLES WHERE SUBSTR(TABLE_NAME,1,2) = 'T_' OR SUBSTR(TABLE_NAME,1,4) = 'TAX_';

LV_SQL LONG;

BEGIN

FOR V_TABLE IN CUR_TABLE LOOP

LV_SQL := 'CREATE SNAPSHOT LOG ON '||V_TABLE.TABLE_NAME||'

TABLESPACE '||TABLESPACE_NAME||' STORAGE (INITIAL 100K NEXT 150K PCTINCREASE 0)';

EXECUTE IMMEDIATE LV_SQL;

END LOOP;

END PRO_WF_SNAPSHOST_LOG;

/

第二步:

在目的数据库中建立如下函数(供以下过程调用)。

CREATE OR REPLACE FUNCTION FUN_CUR_GET_PK_CONDIT_EQUAL

(AV_SCHEME IN VARCHAR2,

AV_TABLE IN VARCHAR2,

CONDITION VARCHAR2,

PK_KIND VARCHAR2,

IS_POINT VARCHAR2 )

RETURN VARCHAR2 AS

CURSOR CUR_COL IS

SELECT COLUMN_NAME CN FROM ALL_CONS_COLUMNS

WHERE OWNER = AV_SCHEME AND CONSTRAINT_NAME IN

(SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS

WHERE OWNER = AV_SCHEME AND TABLE_NAME = AV_TABLE AND CONSTRAINT_TYPE = 'P');

LV_PKSTRING VARCHAR2(4000);

BEGIN

LV_PKSTRING := '';

FOR V_COL IN CUR_COL LOOP

IF IS_POINT = 'Y' THEN

LV_PKSTRING := LV_PKSTRING||' '||PK_KIND|| ' '||V_COL.CN||' = '||CONDITION||'.'||V_COL.CN;

ELSE

LV_PKSTRING := LV_PKSTRING||' '||PK_KIND|| ' '||V_COL.CN||' = '||V_COL.CN;

END IF;

END LOOP;

IF IS_POINT = 'Y' THEN

LV_PKSTRING := FUN_CUR_SUBSTR(LV_PKSTRING,'L',5,0);

ELSE

LV_PKSTRING := FUN_CUR_SUBSTR(LV_PKSTRING,'L',3,0);

END IF;

--去掉左边5个字符' AND '

RETURN LV_PKSTRING;

END FUN_CUR_GET_PK_CONDIT_EQUAL;

/ CREATE OR REPLACE FUNCTION FUN_CUR_GET_FIELD_CONDIT_EQUAL

(AV_SCHEME VARCHAR2,AV_TABLE VARCHAR2,CONDITION VARCHAR2,

KIND VARCHAR2)

RETURN LONG AS

CURSOR CUR_FIELD IS

SELECT COLUMN_NAME CNAME FROM ALL_TAB_COLUMNS

WHERE OWNER = AV_SCHEME AND TABLE_NAME = AV_TABLE

MINUS

SELECT COLUMN_NAME CNAME FROM ALL_CONS_COLUMNS

WHERE OWNER = AV_SCHEME AND CONSTRAINT_NAME IN

(SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS

WHERE OWNER = AV_SCHEME AND TABLE_NAME = AV_TABLE AND CONSTRAINT_TYPE = 'P');

CURSOR CUR_ALL_FIELD IS

SELECT COLUMN_NAME CNAME FROM ALL_TAB_COLUMNS

WHERE OWNER = AV_SCHEME AND TABLE_NAME = AV_TABLE

ORDER BY COLUMN_ID;

LV_FIELDSTRING LONG;

BEGIN

LV_FIELDSTRING := '';

IF KIND='Y' THEN

FOR V_FIELD IN CUR_FIELD LOOP LV_FIELDSTRING := LV_FIELDSTRING ||','||V_FIELD.CNAME||' = '||CONDITION||'.'||V_FIELD.CNAME;

END LOOP;

ELSE

FOR V_ALL_FIELD IN CUR_ALL_FIELD LOOP

LV_FIELDSTRING := LV_FIELDSTRING ||','||CONDITION||'.'||V_ALL_FIELD.CNAME;

END LOOP;

END IF;

RETURN FUN_CUR_SUBSTR(LV_FIELDSTRING,'L',1,0);

--加上',',返回

END FUN_CUR_GET_FIELD_CONDIT_EQUAL;

第三步:在目的数据库中建立如下过程(创建快照与触发器)。

CREATE OR REPLACE PROCEDURE PRO_WF_SNAPSHOST

(DBLINK IN VARCHAR2,--dblink名称

TABLESPACE_NAME IN VARCHAR2,--表空间名称

REFRESH_KIND IN VARCHAR2,--参数值为COMPLETE,FORCE,FAST三种

STARTDATE IN OUT VARCHAR2,--默认为10分钟刷新一次,可不输入

NEXTDATE IN OUT VARCHAR2--默认为10分钟刷新一次,可不输入) AS

CURSOR CUR_TABLE IS

SELECT TABLE_NAME FROM USER_TABLES WHERE SUBSTR(TABLE_NAME,1,2) = 'T_' OR SUBSTR(TABLE_NAME,1,4) = 'TAX_';

LV_SQL LONG;

LV_FIELD VARCHAR2(4000);

LV_FIELD_UPDATE LONG;

LV_PK VARCHAR2(100);

LV_SCHEME VARCHAR2(60);

LV_FIELD_VALUE LONG;

LV_TABLE_NAME VARCHAR2(30);

BEGIN

IF STARTDATE IS NULL THEN

STARTDATE := 'SYSDATE+10/(24*60)';--也可以写成SYSDATE+600/(24*60*60)每十分钟刷新一次

END IF;

IF NEXTDATE IS NULL THEN

NEXTDATE := 'SYSDATE+10/(24*60)';--也可以写成SYSDATE+600/(24*60*60)每十分钟刷新一次

END IF;

FOR V_TABLE IN CUR_TABLE LOOP

LV_TABLE_NAME := V_TABLE.TABLE_NAME;

IF LENGTH(LV_TABLE_NAME)>20 THEN

LV_TABLE_NAME := SUBSTR(LV_TABLE_NAME,0,20);

END IF;

LV_SQL := ' CREATE SNAPSHOT SN_'||LV_TABLE_NAME||' STORAGE (INITIAL 100K NEXT 150K PCTINCREASE 0)

TABLESPACE '|| TABLESPACE_NAME ||' REFRESH '||REFRESH_KIND||' START WITH '||STARTDATE||

' NEXT '|| NEXTDATE||'

AS SELECT * FROM '||V_TABLE.TABLE_NAME||'@'||DBLINK;

EXECUTE IMMEDIATE LV_SQL;

SELECT USERNAME INTO LV_SCHEME FROM USER_USERS;

LV_PK := FUN_CUR_GET_PK_CONDIT_EQUAL(LV_SCHEME,V_TABLE.TABLE_NAME,':OLD','AND','Y');

LV_FIELD_UPDATE := FUN_CUR_GET_FIELD_CONDIT_EQUAL(LV_SCHEME,V_TABLE.TABLE_NAME,':NEW','Y');

LV_FIELD := FUN_CUR_GET_ALL_TABLE_FIELD(LV_SCHEME,V_TABLE.TABLE_NAME); LV_FIELD := SUBSTR(LV_FIELD,1,LENGTH(LV_FIELD)-1);

LV_FIELD := FUN_CUR_SUBSTR(LV_FIELD,'L',1,0);

LV_FIELD_VALUE := FUN_CUR_GET_FIELD_CONDIT_EQUAL(LV_SCHEME,V_TABLE.TABLE_NAME,':NEW','N');

IF LV_FIELD_UPDATE IS NULL THEN

LV_FIELD_UPDATE := FUN_CUR_GET_PK_CONDIT_EQUAL(LV_SCHEME,V_TABLE.TABLE_NAME,NULL,',','N');

END IF; LV_SQL := 'CREATE OR REPLACE TRIGGER TR_SN_'||LV_TABLE_NAME||'_AFR

AFTER INSERT OR UPDATE OR DELETE ON SN_'||LV_TABLE_NAME||'

FOR EACH ROW

BEGIN

IF DELETING THEN

DELETE FROM '||V_TABLE.TABLE_NAME||' WHERE '||LV_PK||';

END IF;

IF INSERTING THEN

INSERT INTO '||V_TABLE.TABLE_NAME||' ('||LV_FIELD||')

VALUES('||LV_FIELD_VALUE||');

END IF; IF UPDATING THEN UPDATE '||V_TABLE.TABLE_NAME||' SET '||LV_FIELD_UPDATE||' WHERE '||LV_PK||'; END IF;

END TR_SN_'||LV_TABLE_NAME||'_AFR;';

EXECUTE IMMEDIATE LV_SQL;

END LOOP;

END PRO_WF_SNAPSHOST;

最后:

执行PRO_WF_SNAPSHOST_LOG过程创所有表的快照日志,然后再执行PRO_WF_SNAPSHOST过程来完成快照的建立和触发器的创建即可完成所有操作。

分享到:
评论

相关推荐

    数据库同步热备解决方案(某区政府)

    本方案针对某区政府的需求,旨在提供一套完整的数据库同步和热备份策略,确保在主数据库出现故障时,能够迅速切换至备份系统,避免数据丢失,减少业务中断时间。 首先,我们需要理解数据库同步的基本概念。数据库...

    同步两个SQLServer数据库

    SQL Server提供了多种同步策略,包括事务复制、合并复制和快照复制。事务复制适用于实时、双向的同步,而合并复制适合多主节点间的异步同步,快照复制则适用于定期的批量更新。 实施步骤如下: 1. **环境准备**:...

    数据库同步的解决方案,图文解说

    数据库同步是一种确保多台计算机上的数据库保持一致性的技术。在SQL Server 2000、SQL Server 2005和SQL Server 2008中,提供了内置的数据库同步功能,无需编写额外的代码就能实现。以下是实现数据库同步的详细步骤...

    SERVER2000数据库,实现数据同步

    配置复制时,需要在发布服务器上创建发布,定义要复制的项目和同步策略。接着,在订阅服务器上创建订阅,指定订阅的发布和同步方式。最后,启动复制过程,确保数据开始流动并保持同步。 总之,SQL Server 2000的...

    基于SQL Server的数据同步方案的研究及应用.pdf

    1) 选择合适的同步策略:根据业务需求选择快照、事务或合并发布,避免过度同步导致资源浪费。 2) 使用索引和分区:对经常查询的数据创建索引,对大数据表进行分区,提高数据检索速度。 3) 定期清理无用数据:避免...

    SQL2000 数据同步教程

    ### SQL2000 数据同步教程:数据库同步机制详解 #### 一、SQL Server 2000数据库同步概述 数据库同步是企业级应用中一个关键的技术环节,它确保了多台服务器之间的数据一致性,特别是在分布式环境中。SQL Server ...

    数据库迁移实施计划方案.doc

    - **物理迁移**:直接复制数据库文件到新环境,适用于相同数据库系统间的迁移。 - **逻辑迁移**:通过导出和导入数据,适用于不同数据库系统间的迁移,可能需要进行数据格式转换。 - **增量迁移**:在初始全量迁移后...

    Redis的持久化方案

    但是,AOF的缺点是文件大小通常会比RDB大得多,尤其是采用默认的每秒同步策略时。此外,如果在日志文件中保存的数据量很大,AOF重写的性能可能会受到影响。 对于Redis持久化,用户可以选择使用单一的RDB或AOF,也...

    金融行业基于数据库的灾备技术

    1. **热备**:在异地建立完全相同的数据库系统,实时同步数据,一旦主系统出现故障,可以立即切换到热备系统,实现无缝接管。 2. **温备**:保持部分数据的同步,或是定期进行数据备份,相比热备,温备的成本较低,...

    利用MSSQL复制技术 实现数据同步.docx

    通过设置和管理发布、订阅和分发,可以实现灵活的数据同步策略。这不仅可以提高数据的可用性和容灾能力,还可以优化数据库性能,特别是在大规模部署和多地点协作的环境中。理解并熟练掌握SQL Server的复制技术,对于...

    SQL SERVER数据库的复制技术.pdf

    通过以上内容的总结,我们可以看到SQL Server数据库的复制技术是一系列复杂的数据同步与分发解决方案,它们能够使数据在不同的数据库系统之间高效、可靠地流动。SQL Server的复制技术不仅提高了数据的可用性和访问...

    使用Oracle物化视图实现数据同步复制的研究与实现.pdf

    1. **环境准备**:确保两台数据库服务器(如文中提到的TESTMAIN和TESTREP)安装了相同版本的Oracle数据库,并且操作系统兼容。配置监听器(listener)、tnsnames.ora文件,设置数据库链接(db-link),并调整相关...

    oracle 10g 快照操作方法

    总的来说,Oracle 10g 的快照功能为分布式数据库环境提供了灵活的数据同步解决方案,通过定时刷新机制,确保了数据的实时性和一致性。然而,正确配置和管理快照是非常关键的,需要根据具体需求选择合适的刷新策略,...

    分布式数据同步算法.pptx

    快照同步是一种常见的数据同步机制,它通过在特定时间点创建数据快照来实现数据同步。快照同步算法主要包含以下几个方面: - **时间线和一致性模型**: - 定义:以全局时间线为基础,将数据副本的状态记录在特定...

    MongoDB数据库技术概述.pptx

    如果两个未提交的事务尝试修改相同文档,MongoDB会检测到冲突并处理,如回滚其中一个事务。此外,MongoDB的复制集和分片集群设计还提供了主从同步和数据复制,以确保数据安全和高可用性。 综上所述,MongoDB是应对...

    DB2 V9/10 HADR 数据库部署

    DB2 V9/V10 HADR(High Availability Disaster Recovery)是IBM DB2数据库系统中的一个高可用性和灾难恢复解决方案,用于实现主备数据库之间的同步,确保数据的一致性与连续性。本文将详细介绍DB2 V9/V10版本中HADR...

    ORACLE 10R2 Data Guard Concepts and Administration

    快照备用数据库是在特定时间点创建的主数据库的副本,它不接收实时的重做日志记录,而是依赖于定期的全量或增量备份来同步数据。这种模式下的备用数据库主要用于测试或数据分析,而不是作为故障转移的即时替代品。 ...

    大数据技术分享 Oracle DataGuard基础入门教程 一步一步学DataGuard 共100页.pdf

    4. **Snapshot Standby Database (快照备用数据库)**:这是一种特殊类型的物理备用数据库,它不接受重做日志的应用,因此无法实时更新数据。通常用于查询和报告等只读操作。 #### 三、物理备用数据库的创建与管理 ...

    ORACLE 数据复制技术

    数据同步:** 根据配置的复制策略,定期或实时地比较源数据库和目标数据库之间的数据差异,并进行相应的同步操作。 **4. 冲突解决:** 当数据在多个数据库间存在冲突时,需要有一套完善的机制来解决这些冲突,确保...

    从SQL Server2000升级到2005的过程解析

    原因在于,日志传送无法在不同版本的数据库之间直接进行,只能在相同版本的数据库之间进行NO RECOVERY恢复模式的传送。 2. **拷贝数据库**:使用SQL Server的拷贝数据库向导时,如果源和目标版本不同,系统会报错,...

Global site tag (gtag.js) - Google Analytics