Oracle10gR2 Streams(四)全库复制之二
NinGoo's blog

Oracle10gR2 Streams(四)全库复制之二

上一篇中展示了使用pre_instantiation_setup/post_instantiation_setup结合rman做初始化的方式实现全库复制的过程,可以说是非常的简单。本例将使用maintain_global来配置一个单向的远程捕获的全库复制。Maintain_global使用expdp/impdp来进行初始化,所以需要目标库已经存在。如果源库比较大,采用data pump初始化可能需要比较长的时间。

源库:ning.test
目标库:dest.test

一、配置directory

因为是使用expdp/impdp来执行初始化,所以需要为expdp/impdp创建响应的directory。当然这不是必须的,data pump可以直接通过网络执行导入。

STRMADM@ning>create directory dir_source as ‘f:\oracle\source’;

Directory created.

STRMADM@dest>create directory dir_dest as ‘f:\oracle\dest’;

Directory created.

二、传送源库日志到目标库

alter system set log_archive_dest_2=’service=dest arch noregister’;

三、执行maintain_global

如果要配置成本地捕获,则在源库执行该过程。如果要配置成downstream捕获,则在目标库或者第三个库中执行,本例在目标库中执行,也就是捕获进程和应用进程都在目标库中:

STRMADM@dest>begin
2 DBMS_STREAMS_ADM.MAINTAIN_GLOBAL(
3 source_directory_object => ‘DIR_SOURCE’,
4 destination_directory_object => ‘DIR_DEST’,
5 source_database => ‘ning.test’,
6 destination_database => ‘dest.test’,
7 perform_actions => true,
8 dump_file_name => ‘streams_rep.dmp’,
9 bi_directional => false,
10 include_ddl => true,
11 instantiation => DBMS_STREAMS_ADM.INSTANTIATION_FULL);
12 end;
13 /

PL/SQL procedure successfully completed.

其中,instantiation指定初始化的方式
DBMS_STREAMS_ADM.INSTANTIATION_FULL:expdp全库导出然后impdp全库导入
DBMS_STREAMS_ADM.INSTANTIATION_FULL_NETWORK:使用data pump直接通过网络导入的特性初始化
DBMS_STREAMS_ADM.INSTANTIATION_NONE:不执行初始化。这个选现只有在perform_actions=false的情况下有效,也就是指定先生成脚本,手工初始化,然后在执行配置脚本。

四、验证复制是否成功

在源库上创建table并插入数据

STRMADM@ning>create table ning.teststrm(i int);

Table created.

STRMADM@ning>insert into ning.teststrm values(1);

1 row created.

STRMADM@ning>commit;

Commit complete.

归档当前日志

STRMADM@ning>alter system archive log current;

System altered.

稍等片刻在目标库查询

STRMADM@dest>select * from ning.teststrm;

I
———-
1

至此,单向downstream全库复制成功

五、其他

同样的,maintain_global也是先生成配置脚本再自动执行,也可以分成两步单独执行

STRMADM@dest>begin
2 DBMS_STREAMS_ADM.MAINTAIN_GLOBAL(
3 source_directory_object => ‘DIR_SOURCE’,
4 destination_directory_object => ‘DIR_DEST’,
5 source_database => ‘ning.test’,
6 destination_database => ‘dest.test’,
7 perform_actions => false,
8 script_directory_object =>’DIR_SCRIPT’,
9 script_name => ‘global_script.sql’,
10 dump_file_name => ‘streams_rep.dmp’,
11 bi_directional => false,
12 include_ddl => true,
13 instantiation => DBMS_STREAMS_ADM.INSTANTIATION_NONE);
14 end;
15 /

PL/SQL procedure successfully completed.

生成的f:\oracle\global_script.sql脚本如下


SET ECHO ON
SET VERIFY OFF
WHENEVER SQLERROR EXIT SQL.SQLCODE;

——————————————————————-
– get TNSNAME and streams admin user details for both the databases
——————————————————————–
PROMPT
PROMPT ‘Enter TNS Name of site 1 as parameter 1:’
DEFINE db1 = &1
PROMPT
PROMPT ‘Enter streams admin username for site 1 as parameter 2:’
DEFINE strm_adm_db1 = &2
PROMPT
PROMPT ‘Enter streams admin password for site 1 as parameter 3:’
DEFINE strm_adm_pwd_db1 = &3
PROMPT
PROMPT ‘Enter TNS Name of site 2 as parameter 4:’
DEFINE db2 = &4
PROMPT
PROMPT ‘Enter streams admin username for site 2 as parameter 5:’
DEFINE strm_adm_db2 = &5
PROMPT
PROMPT ‘Enter streams admin password for site 2 as parameter 6:’
DEFINE strm_adm_pwd_db2 = &6
PROMPT
PROMPT ‘Enter TNS Name of site 3 as parameter 7:’
DEFINE db3 = &7
PROMPT
PROMPT ‘Enter streams admin username for site 3 as parameter 8:’
DEFINE strm_adm_db3 = &8
PROMPT
PROMPT ‘Enter streams admin password for site 3 as parameter 9:’
DEFINE strm_adm_pwd_db3 = &9

– connect as streams administrator to site 1
PROMPT Connecting as streams administrator to site 1
CONNECT &strm_adm_db1/&strm_adm_pwd_db1@&db1

– Add database level supplemental logging

BEGIN
EXECUTE IMMEDIATE ‘ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX, FOREIGN KEY) COLUMNS’;
END;
/

– Dictionary build

BEGIN
dbms_capture_adm.build;
END;
/

– Prepare global instantiation

BEGIN
dbms_capture_adm.prepare_global_instantiation;
END;
/
– connect as streams administrator to site 2
PROMPT Connecting as streams administrator to site 2
CONNECT &strm_adm_db2/&strm_adm_pwd_db2@&db2

– Set up queue “STRMADM”.”NING$CAPQ”

BEGIN
dbms_streams_adm.set_up_queue(
queue_table => ‘”STRMADM”.”NING$CAPQT”‘,
storage_clause => NULL,
queue_name => ‘”STRMADM”.”NING$CAPQ”‘,
queue_user => ”);
END;
/

– PROPAGATE changes for all objects in the database

DECLARE
version_num NUMBER := 0;
release_num NUMBER := 0;
pos NUMBER;
initpos NUMBER;
q2q BOOLEAN;
stmt VARCHAR2(100);
ver VARCHAR2(30);
compat VARCHAR2(30);

BEGIN
BEGIN
stmt := ‘BEGIN dbms_utility.db_version@DEST.TEST(:ver, :compat); END;’;
EXECUTE IMMEDIATE stmt USING OUT ver, OUT compat;
— Extract version number
initpos := 1;
pos := INSTR(compat, ‘.’, initpos, 1);
IF pos > 0 THEN
version_num := TO_NUMBER(SUBSTR(compat, initpos, pos – initpos));
initpos := pos + 1;

— Extract release number
pos := INSTR(compat, ‘.’, initpos, 1);
IF pos > 0 THEN
release_num := TO_NUMBER(SUBSTR(compat, initpos,
pos – initpos));
initpos := pos + 1;
ELSE
release_num := TO_NUMBER(SUBSTR(compat, initpos));
END IF;
ELSE
version_num := TO_NUMBER(SUBSTR(compat, initpos));
END IF;

— use q2q propagation if compatibility >= 10.2
IF version_num > 10 OR
(version_num = 10 AND release_num >=2) THEN
q2q := TRUE;
ELSE
q2q := FALSE;
END IF;

EXCEPTION WHEN OTHERS THEN
q2q := FALSE;
END;

dbms_streams_adm.add_global_propagation_rules(
streams_name => ”,
source_queue_name => ‘”STRMADM”.”NING$CAPQ”‘,
destination_queue_name => ‘”STRMADM”.”NING$APPQ”‘,
include_dml => TRUE,
include_ddl => TRUE,
include_tagged_lcr => TRUE,
source_database => ‘NING.TEST’,
inclusion_rule => TRUE,
and_condition => NULL,
queue_to_queue => q2q);
END;
/

– Disable propagation. Enable after destination has been setup

DECLARE
q2q VARCHAR2(10);
destn_q VARCHAR2(65);
BEGIN
SELECT queue_to_queue INTO q2q
FROM dba_propagation
WHERE source_queue_owner = ‘STRMADM’ AND
source_queue_name = ‘NING$CAPQ’ AND
destination_queue_owner = ‘STRMADM’ AND
destination_queue_name = ‘NING$APPQ’ AND
destination_dblink = ‘AQ$_LOCAL’;

IF q2q = ‘TRUE’ THEN
destn_q := ‘”STRMADM”.”NING$APPQ”‘;
ELSE
destn_q := NULL;
END IF;

dbms_aqadm.disable_propagation_schedule(
queue_name => ‘”STRMADM”.”NING$CAPQ”‘,
destination => ”,
destination_queue => destn_q);
EXCEPTION WHEN OTHERS THEN
IF sqlcode = -24065 THEN NULL; — propagation already disabled
ELSE RAISE;
END IF;
END;
/

– Create downstream capture NING$CAP

DECLARE
cnt NUMBER;
first_scn NUMBER;
BEGIN
SELECT COUNT(*) INTO cnt
FROM dba_capture
WHERE capture_name = ‘NING$CAP’;

— Create capture only if the process does not exist.
IF cnt = 0 THEN
SELECT MAX(first_change#) INTO first_scn
FROM v$archived_log@NING.TEST
WHERE dictionary_begin = ‘YES’ AND
first_change# <= (SELECT MAX(first_change#)
FROM v$archived_log@NING.TEST
WHERE dictionary_end = 'YES');

dbms_capture_adm.create_capture(
queue_name=> ‘”STRMADM”.”NING$CAPQ”‘,
capture_name=> ‘”NING$CAP”‘,
use_database_link => FALSE,
first_scn => first_scn,
source_database=> ‘NING.TEST’);
END IF;
END;
/

– CAPTURE changes for all objects in the database

DECLARE
compat VARCHAR2(512);
initpos NUMBER;
pos NUMBER;
version_num NUMBER;
release_num NUMBER;
compat_func VARCHAR2(65);
get_compatible VARCHAR2(4000);
BEGIN
SELECT value INTO compat
FROM v$parameter
WHERE name = ‘compatible’;

— Extract version number
initpos := 1;
pos := INSTR(compat, ‘.’, initpos, 1);
IF pos > 0 THEN
version_num := TO_NUMBER(SUBSTR(compat, initpos, pos – initpos));
initpos := pos + 1;

— Extract release number
pos := INSTR(compat, ‘.’, initpos, 1);
IF pos > 0 THEN
release_num := TO_NUMBER(SUBSTR(compat, initpos, pos – initpos));
initpos := pos + 1;
ELSE
release_num := TO_NUMBER(SUBSTR(compat, initpos));
END IF;
END IF;

IF version_num < 10 THEN
compat_func := 'dbms_streams.compatible_9_2';
ELSIF version_num = 10 THEN
IF release_num < 2 THEN
compat_func := 'dbms_streams.compatible_10_1';
ELSE
compat_func := 'dbms_streams.compatible_10_2';
END IF;
ELSE
compat_func := 'dbms_streams.compatible_10_2';
END IF;

get_compatible := ':lcr.get_compatible() <= '||compat_func;

dbms_streams_adm.add_global_rules(
streams_type => ‘CAPTURE’,
streams_name => ‘”NING$CAP”‘,
queue_name => ‘”STRMADM”.”NING$CAPQ”‘,
include_dml => TRUE,
include_ddl => TRUE,
include_tagged_lcr => TRUE,
source_database => ‘NING.TEST’,
inclusion_rule => TRUE,
and_condition => get_compatible);
END;
/

– EXPORT: If export/import is the chosen instantiation method
– do the export here.
– Once export is complete, tranfer the export dump file(s) to the
– appropriate location on the system hosting the destination
– database.


– Start capture process NING$CAP

BEGIN
dbms_capture_adm.start_capture(
capture_name => ‘”NING$CAP”‘);
EXCEPTION WHEN OTHERS THEN
IF sqlcode = -26666 THEN NULL; — CAPTURE process already running
ELSE RAISE;
END IF;
END;
/

– IMPORT: If export/import or datapump network mode import
– is the chosen instantiation method, do the import here.


– RMAN: If RMAN is the chosen instantiation method, do the
– instantiation here. Once the instantiation is complete,
– do the necessary setup on the instantiated database, which
– includes renaming global name and setting up database links.
– Also, choose an appropriate instantiation scn at the source
– and set it as the global instantiation scn at the destination


– Set up queue “STRMADM”.”NING$APPQ”

BEGIN
dbms_streams_adm.set_up_queue(
queue_table => ‘”STRMADM”.”NING$APPQT”‘,
storage_clause => NULL,
queue_name => ‘”STRMADM”.”NING$APPQ”‘,
queue_user => ”);
END;
/

– APPLY changes for all objects in the database

DECLARE
compat VARCHAR2(512);
initpos NUMBER;
pos NUMBER;
version_num NUMBER;
release_num NUMBER;
compat_func VARCHAR2(65);
get_compatible VARCHAR2(4000);
BEGIN
SELECT value INTO compat
FROM v$parameter
WHERE name = ‘compatible’;

— Extract version number
initpos := 1;
pos := INSTR(compat, ‘.’, initpos, 1);
IF pos > 0 THEN
version_num := TO_NUMBER(SUBSTR(compat, initpos, pos – initpos));
initpos := pos + 1;

— Extract release number
pos := INSTR(compat, ‘.’, initpos, 1);
IF pos > 0 THEN
release_num := TO_NUMBER(SUBSTR(compat, initpos, pos – initpos));
initpos := pos + 1;
ELSE
release_num := TO_NUMBER(SUBSTR(compat, initpos));
END IF;
END IF;

IF version_num < 10 THEN
compat_func := 'dbms_streams.compatible_9_2';
ELSIF version_num = 10 THEN
IF release_num < 2 THEN
compat_func := 'dbms_streams.compatible_10_1';
ELSE
compat_func := 'dbms_streams.compatible_10_2';
END IF;
ELSE
compat_func := 'dbms_streams.compatible_10_2';
END IF;

get_compatible := ':lcr.get_compatible() <= '||compat_func;

dbms_streams_adm.add_global_rules(
streams_type => ‘APPLY’,
streams_name => ”,
queue_name => ‘”STRMADM”.”NING$APPQ”‘,
include_dml => TRUE,
include_ddl => TRUE,
include_tagged_lcr => TRUE,
source_database => ‘NING.TEST’,
inclusion_rule => TRUE,
and_condition => get_compatible);
END;
/

– Get tag value to be used for Apply

DECLARE
found BINARY_INTEGER := 0;
tag_num NUMBER;
apply_nm VARCHAR2(30);
apply_nm_dqt VARCHAR2(32);
BEGIN
SELECT apply_name INTO apply_nm
FROM dba_apply_progress
WHERE source_database = ‘NING.TEST’;

apply_nm_dqt := ‘”‘ || apply_nm || ‘”‘;
— Use the apply object id as the tag
SELECT o.object_id INTO tag_num
FROM dba_objects o
WHERE o.object_name= apply_nm AND
o.object_type=’APPLY’;
LOOP
BEGIN
found := 0;
SELECT 1 INTO found FROM dba_apply
WHERE apply_name != apply_nm AND
apply_tag = hextoraw(tag_num);
EXCEPTION WHEN no_data_found THEN
EXIT;
END;
EXIT WHEN (found = 0);
tag_num := tag_num + 1;
END LOOP;
— alter apply
dbms_apply_adm.alter_apply(
apply_name => apply_nm_dqt,
apply_tag => hextoraw(tag_num));
END;
/

– Start apply process applying changes from NING.TEST

DECLARE
apply_nm VARCHAR2(32);
apply_nm_dqt VARCHAR2(32);
BEGIN
SELECT apply_name INTO apply_nm
FROM dba_apply_progress
WHERE source_database = ‘NING.TEST’;

apply_nm_dqt := ‘”‘ || apply_nm || ‘”‘;
dbms_apply_adm.start_apply(
apply_name => apply_nm_dqt);
EXCEPTION WHEN OTHERS THEN
IF sqlcode = -26666 THEN NULL; — APPLY process already running
ELSE RAISE;
END IF;
END;
/

– Enable propagation schedule for “STRMADM”.”NING$CAPQ”
– to DEST.TEST

DECLARE
q2q VARCHAR2(10);
destn_q VARCHAR2(65);
BEGIN
SELECT queue_to_queue INTO q2q
FROM dba_propagation
WHERE source_queue_owner = ‘STRMADM’ AND
source_queue_name = ‘NING$CAPQ’ AND
destination_queue_owner = ‘STRMADM’ AND
destination_queue_name = ‘NING$APPQ’ AND
destination_dblink = ‘AQ$_LOCAL’;

IF q2q = ‘TRUE’ THEN
destn_q := ‘”STRMADM”.”NING$APPQ”‘;
ELSE
destn_q := NULL;
END IF;

dbms_aqadm.enable_propagation_schedule(
queue_name => ‘”STRMADM”.”NING$CAPQ”‘,
destination => ”,
destination_queue => destn_q);
EXCEPTION WHEN OTHERS THEN
IF sqlcode = -24064 THEN NULL; — propagation already enabled
ELSE RAISE;
END IF;
END;
/

本文网址:http://www.ningoo.net/html/2007/oracle10gr2_streams_database_level_replication_2.html

订阅到Google | 收藏到Del.icio.us | 推荐到鲜果

上一篇: 下一篇:
相关文章 随机文章

本文Tags: ,

1 条评论


(Required)
(Required, will not be published)