Streams 特性在oracle诸多特性中属于比较灵活的一个,如果你接触oracle的时候足够久,那么一定能够理解,对于oracle而言,灵活往往也意味着复杂。这样也可以,那样也可以,究竟怎样好?一直以来,俺都认为实践更加有助于理解,为了更有有效的帮助大家的理解和学习,俺决定首先通过一个简单的示例来演示streams大致的工作方法。
一、要求
1 、 初始化参数的修改
- global_names 必须设置为true,global_name=db_name+db_domain。
- job_queue_processes 必须>2
- compatible ,必须高于10.2.0,并且target中该参数值不能低于source database.
- streams_pool_size, 指定适当的大小 ( 建议不小于200M) ,当然如果设置了sga_target,该参数也可由系统自动调节
2 、 source database 必须启用归档模式
3 、 双机互相创建database link
4 、为方便区分,我们对源和目标库的操作符做初始化
SOURCE 端:
SQL> conn / as sysdba
已连接。
SQL> set sqlprompt "JSSWEB> "
TARGET 端:
SQL> conn / as sysdba
已连接。
SQL> set sqlprompt "JSS STR > "
二、创建用户及搭建环境
这里设定我们的source数据库是jssweb,target数据库是jssstr,数据库版本10201,两机准备工作均已做好(主要指上面说的那几条)
1 、一个一个来吧,首先自然是source
-- 创建一个专用于streams的表空间,很有必要
JSSWEB> create tablespace stream_tbs datafile ¨E:\oracle\oradata\jssweb\stream01.dbf¨ size 200m;
表空间已创建。
-- 创建streams管理用户,并授予dba权限
JSSWEB> create user stradmin identified by stradmin default tablespace stream_tbs;
用户已创建。
-- 由于streams用户操作需要较多权限,此处仅用于演示,简便期间直接授予dba权限
JSSWEB> grant dba to stradmin;
授权成功。
2 、target当然也是同理,创建专用表空间及用户。
JSSSTR> create tablespace stream_tbs datafile ¨E:\oracle\oradata\jssstr\stream01.dbf¨ size 200m;
表空间已创建。
JSSSTR> create user stradmin identified by stradmin default tablespace stream_tbs;
用户已创建。
JSSSTR> grant dba to stradmin;
授权成功。
3 、切换回source数据库,以streams的操作用户stradmin连接
JSSWEB> conn stradmin/stradmin
已连接。
创建连接到target的数据库链:
JSSWEB> create database link jssstr connect to stradmin identified by stradmin using ¨jssstr¨;
数据库链接已创建。
JSSWEB> select sysdate from dual@jssstr;
SYSDATE
-------------------
2008-09-01 10:18:24
-- 创建队列
JSSWEB> exec dbms_streams_adm.set_up_queue();
PL/SQL 过程已成功完成。
4 、再次切换到target数据库,以streams的操作用户stradmin连接
JSSSTR> conn stradmin/stradmin
已连接。
JSSSTR> create database link jssweb connect to stradmin identified by stradmin using ¨jssweb¨;
数据库链接已创建。
JSSSTR> select sysdate from dual@jssweb;
SYSDATE
--------------
2008-09-01 10:24:38
-- 创建队列
JSSSTR> exec dbms_streams_adm.set_up_queue();
PL/SQL 过程已成功完成。
三、配置复制过程
1 、首先到source数据库
创建捕获规则
JSSWEB> begin
2 dbms_streams_adm.add_table_rules(
3 table_name => ¨scott.emp¨,
4 streams_type => ¨capture¨,
5 streams_name => ¨capture_stream¨,
6 queue_name => ¨stradmin.streams_queue¨,
7 include_dml => true,
8 include_ddl => true,
9 inclusion_rule => true);
10 end;
11 /
PL/SQL 过程已成功完成。
创建传播规则
JSSWEB> begin
2 dbms_streams_adm.add_table_propagation_rules(
3 table_name => ¨scott.emp¨,
4 streams_name => ¨sour_to_targ¨,
5 source_queue_name => ¨stradmin.streams_queue¨,
6 destination_queue_name => ¨stradmin.streams_queue@jssstr.jss.cn¨,
7 include_dml => true,
8 include_ddl => true,
9 source_database => ¨jssweb.jss.cn¨,
10 inclusion_rule => true,
11 queue_to_queue => true);
12 end;
13 /
PL/SQL 过程已成功完成。
JSSWEB> select capture_name,status from dba_capture;
CAPTURE_NAME STATUS
------------------------------ --------
CAPTURE_STREAM DISABLED
2 、切换到target数据库
创建应用规则
JSSSTR> begin
2 dbms_streams_adm.add_table_rules(
3 table_name => ¨scott.emp¨,
4 streams_type => ¨apply¨,
5 streams_name => ¨apply_stream¨,
6 queue_name => ¨stradmin.streams_queue¨,
7 include_dml => true,
8 include_ddl => true,
9 source_database => ¨jssweb.jss.cn¨,
10 inclusion_rule => true);
11 end;
12 /
PL/SQL 过程已成功完成。
初始化数据,首先从源库导出,再执行导入,复制的方式很多,逻辑导入导出、rman、duplication之类的,基本上你想怎么操作都可以,这里因为只操作一个表,三思决定直接通过数据库链复制。
JSSSTR> create table scott.EMP
2 (
3 EMPNO NUMBER(4) not null primary key ,
4 ENAME VARCHAR2(10),
5 JOB VARCHAR2(9),
6 MGR NUMBER(4),
7 HIREDATE DATE,
8 COMM NUMBER(7,2),
9 DEPTNO NUMBER(2)
10 );
表已创建。
JSSSTR> insert into scott.emp select *from scott.emp@jssweb;
已创建13行。
JSSSTR> commit;
提交完成。
设置起始应用的scn值
JSSSTR> DECLARE
2 iscn NUMBER;
3 BEGIN
4 iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();
5 DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@jssstr.jss.cn(
6 source_object_name => ¨scott.emp¨,
7 source_database_name => ¨jssweb.jss.cn¨,
8 instantiation_scn => iscn);
9 END;
10 /
PL/SQL 过程已成功完成。
启动应用进程
JSSSTR> exec dbms_apply_adm.start_apply(¨apply_stream¨);
PL/SQL 过程已成功完成。
JSSSTR> select apply_name,status from dba_apply;
APPLY_NAME STATUS
------------------------------ --------
APPLY_STREAM ENABLED
3 、切换到source数据库,启动捕获进程
JSSWEB> exec dbms_capture_adm.start_capture(¨capture_stream¨);
PL/SQL 过程已成功完成。
JSSWEB> select capture_name,status from dba_capture;
CAPTURE_NAME STATUS
------------------------------ --------
CAPTURE_STREAM ENABLED
四、测试
如果一切顺利,我们的streams就配置好了,下面验证一下。
JSSWEB> select *from scott.emp where empno=7499;
EMPNO ENAME JOB MGR HIREDATE COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ----------
7499 ALLEN SALESMAN 7698 20-2 月 -81 300 30
JSSWEB> update scott.emp set deptno=40 where empno=7499;
已更新 1 行。
JSSWEB> commit;
提交完成。
JSSSTR> select * from scott.emp where empno=7499;
EMPNO ENAME JOB MGR HIREDATE COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ----------
7499 ALLEN SALESMAN 7698 20-2 月 -81 300 40
JSSWEB> alter table scott.emp add tmpcol varchar2(10);
表已更改。
JSSSTR> desc scott.emp;
名称 是否为空? 类型
--------------- -------- --------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
TMPCOL VARCHAR2(10)
由以上测试可以看到,dml,ddl操作均可顺利传输并应用于target端,streams单表单向复制完成~~
|