配置ORACLE 10G streams 高级流复制技术

时间:2022-09-14 23:34:31
 

------本文摘自 http://wenku.baidu.com/view/cdd9810e4a7302768e993934.html

Internet上运作数据库经常会有这样的需求:把遍布全国各城市相似的数据库应用统一起来,一个节点的数据改变不仅体现在本地,还反映到远端。复制技术给用户提供了一种快速访问共享数据的办法。

前提条件
要准备2台测试用的机器,开始制作如下:
2台机器安装oracle10g,注意我的版本相同。
SID都是music1
1:安装及运行vnc。。。用于远程安装oracle
2:安装及运行 oracle10.2....
完成以上步骤后,基本工作就算做完了,现在开始配置高级复制。
假设数据库机器为 数据库机器A ...数据库机器B...
数据库机器A地址为;192.168.1.205
SID:ciscosys
域名:ciscosys
数据库机器B地址为;192.168.1.226
SID:book
域名:book
首先配置确认俩台机器可以互相访问,如下:
机器A操作:
用oracle登陆
修改如下文件;
vi tnsnames.ora
添加:
book =        这个名称随便起
  (DE.ION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.226)(PORT = 1521))    这里为机器B的地址及数据库端口号
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = music1)    这个名称为机器B 数据库SID的值
    )
  )
配置完重起数据库

机器B操作:
用oracle登陆
同样修改如下文件;
vi tnsnames.ora
添加:
ciscosys =        这个名称随便起
  (DE.ION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.205)(PORT = 1522))    这里为机器A的地址及数据库端口号
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = music1)    这个名称为机器A 数据库SID的值
    )
  )
重起数据库
测试数据库连通性,在机器A如下;
[oracle@localhost admin]$ tnsping book
显示如下;
TNS Ping Utility for Linux: Version 10.2.0.1.0 - Production . 04-JAN-2009 16:53:23

Copyright (c) 1997, 2005, Oracle.  All rights reserved.

Used parameter files:
/home/oracle/oracle/product/10.2.0/network/admin/sqlnet.ora


Used TNSNAMES adapter to resolve the alias
Attempting to contact (DE.ION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.226)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = music1)))
OK (10 msec)
 
测试数据库连通性,在机器B如下;
[oracle@localhost admin]$ tnsping ciscosys
显示;
TNS Ping Utility for Linux: Version 10.2.0.1.0 - Production . 04-JAN-2009 17:09:04

Copyright (c) 1997, 2005, Oracle.  All rights reserved.

Used parameter files:
/home/oracle/oracle/product/10.2.0/network/admin/sqlnet.ora

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DE.ION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.205)(PORT = 1522)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = music1)))
OK (0 msec)

注意:这里我的2台机器没有加防火墙等其他安全措施,数据库也没有设置限制地址登陆。如果你连接不上,就仔细看看自己的其他配置。

接着在机器A操作如下:
察看v$option,Advanced replication为TRUE,则支持高级复制功能;否则不支持
select * from v$option;
以上察看结果默认为ture,支持高级复制。

察看global_name参数
SQL> show parameter global_name;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
global_names                         boolean     FALSE
看过大多数文章都将这里要设置成true,我没有改动,默认false使用,


察看默认global_name,数据库域名
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
ciscosys.REGRESS.RDBMS.DEV.US.ORACLE.COM

修改global_name,数据库域名
SQL> alter database rename global_name to ciscosys;
察看修改结果;
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
ciscosysy

创建帐户及数据:
SQL> create user wcms identified by abc123 default tablespace users;
SQL>grant connect,resource to wcms;
切换到wcms,
SQL> conn wcms/abc123
创建表
SQL> create table test(id number,name varchar2(20),constraint test_id_pk primary key(id));   (主键一定是要的);
插入数据
SQL> insert into test values(1,'abc');
SQL> insert into test values(2,'def');
建立管理数据库复制的用户strmadmin,并赋权。

SQL>conn /as sysdba
SQL> create user strmadmin identified by strmadmin default tablespace users temporary tablespace temp;
SQL> execute dbms_defer_sys.register_propagator('strmadmin');
SQL> grant execute any procedure to strmadmin;
SQL> execute dbms_repcat_admin.grant_admin_any_repgroup('strmadmin');
SQL> execute dbms_repcat_admin.grant_admin_any_schema(username => 'strmadmin');
SQL> grant comment any table to strmadmin;
SQL> grant lock any table to strmadmin;
SQL> grant select any dictionary to strmadmin;
用strmadmin 创建database link 连接
SQL> conn strmadmin/strmadmin
SQL> create database link "book" connect to strmadmin identified by strmadmin using 'book';
说明一下;sbook为我修改global_name的值
music226 :是以上tnsnames.ora中我设定连接机器B数据库的值
察看一下:SQL> select owner,db_link,host from all_db_links;
OWNER         DB_LINK                                 HOST  

STRMADMIN  book    book


在机器B操作如下;
察看v$option,Advanced replication为TRUE,则支持高级复制功能;否则不支持
select * from v$option;
以上察看结果默认为ture,支持高级复制。
察看global_name参数
SQL> show parameter global_name;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
global_names                     boolean     FALSE

察看默认global_name,数据库域名
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
MUSIC1.REGRESS.RDBMS.DEV.US.ORACLE.COM
修改global_name,数据库域名
SQL> alter database rename global_name to book;
察看修改结果;
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
book

创建帐户及数据:
SQL> create user wcms identified by abc123 default tablespace users;
SQL>grant connect,resource to wcms;
切换到wcms,
SQL> conn wcms/abc123
创建表
SQL> create table test(id number,name varchar2(20),constraint test_id_pk primary key(id));   (主键一定是要的);
插入数据
SQL> insert into test values(1,'zhao');
SQL> insert into test values(2,'yong');
配置复制管理用户

SQL>conn /as sysdba

建立管理数据库复制的用户strmadmin,并赋权。
SQL> create user strmadmin identified by strmadmin default tablespace users temporary tablespace temp;
SQL> execute dbms_defer_sys.register_propagator('strmadmin');
SQL> grant execute any procedure to strmadmin;
SQL> execute dbms_repcat_admin.grant_admin_any_repgroup('strmadmin');
SQL> execute dbms_repcat_admin.grant_admin_any_schema(username => 'strmadmin');
SQL> grant comment any table to strmadmin;
SQL> grant lock any table to strmadmin;
SQL> grant select any dictionary to strmadmin;
用strmadmin 创建database link 连接

SQL>
SQL> create database link "ciscosys" connect to strmadmin identified by strmadmin using 'ciscosys';
说明一下;master.anymusic.com为我修改global_name的值
music205 :是以上tnsnames.ora中我设定连接机器A数据库的值
察看一下:SQL> select owner,db_link,host from all_db_links;
SQL> select owner,db_link,host from all_db_links;
OWNER            DB_LINK                                      HOST
--------------------------------------------------------------------------------
STRMADMIN     ciscosys     ciscosys

测试开始
登陆机器A
测试数据库链接:
SQL> select * from global_name@book;
显示:
GLOBAL_NAME
--------------------------------------------------------------------------------
book
表示数据库到此连接成功

登陆机器B
测试数据库链接:
SQL> select * from global_name@ciscosys;
显示:
GLOBAL_NAME
--------------------------------------------------------------------------------
ciscosys
表示数据库到此连接成功。

3.5 启用追加日志 

可以基于Database级别或Table级别,启用追加日志(Supplemental Log)。在建立根据Schema粒度进行复制的Oracle Stream环境中,如果确认Schema下所有Table都有合理的主键(Primary Key),则不再需要启用追加日志。 

 

#启用Database 追加日志 

alter database add supplemental log data; 

 

#启用Table追加日志 

alter table add supplement log group log_group_name(table_column_name) always; 

 

3.7 创建流队列 

3.7.1创建Master流队列 

#strmadmin身份,登录主数据库。 

connect strmadmin/strmadmin 

 

begin 

dbms_streams_adm.set_up_queue( 

queue_table => 'ciscosys_queue_table', 

queue_name => 'ciscosys_queue'); 

end; 

3.7.2创建Backup流队列 

#strmadmin身份,登录从数据库。 

connect strmadmin/strmadmin 

 

begin 

dbms_streams_adm.set_up_queue( 

queue_table => 'book_queue_table', 

queue_name => 'book_queue'); 

end; 

 

3.8 创建捕获进程 

#strmadmin身份,登录主数据库。提醒一下,本文档以hr用户做示例。 

connect strmadmin/strmadmin 

 

begin 

dbms_streams_adm.add_schema_rules( 

schema_name => 'hr', 

streams_type => 'capture', 

streams_name => 'capture_ciscosys', 

queue_name => 'strmadmin.ciscosys_queue', 

include_dml => true, 

include_ddl => true, 

include_tagged_lcr => false, 

source_database => null, 

inclusion_rule => true); 

end; 

3.9 实例化复制数据库 

在主数据库环境中,执行如下Shell语句。如果从库的hr用户不存在,建立一个hr的空用户。 

exp userid=hr/hr@ciscosys file='f:\hr.dmp' object_consistent=y rows=y 

exp userid=hr/hr@ciscosys file='f:\hr.dmp' object_consistent=y rows=y

 

 

imp userid=system/manager@book file='f:\hr.dmp' ignore=y commit=y log='f:\hr.log' streams_instantiation=y fromuser=hr touser=hr 

3.10 创建传播进程 

#strmadmin身份,登录主数据库。 

connect strmadmin/strmadmin 

 

begin 

dbms_streams_adm.add_schema_propagation_rules( 

schema_name => 'hr', 

streams_name => 'ciscosys_to_book', 

source_queue_name => 'strmadmin.ciscosys_queue', 

destination_queue_name => 'strmadmin.book_queue@book', 

include_dml => true, 

include_ddl => true, 

include_tagged_lcr => false, 

source_database => 'ciscosys', 

inclusion_rule => true); 

end; 

 

#修改propagation休眠时间为0,表示实时传播LCR 

begin 

dbms_aqadm.alter_propagation_schedule( 

queue_name => 'ciscosys_queue', 

destination => 'book', 

latency => 0); 

end; 

3.11 创建应用进程 

#strmadmin身份,登录从数据库。 

connect strmadmin/strmadmin 

 

begin 

dbms_streams_adm.add_schema_rules( 

schema_name => 'hr', 

streams_type => 'apply', 

streams_name => 'apply_book', 

queue_name => 'strmadmin.book_queue', 

include_dml => true, 

include_ddl => true, 

include_tagged_lcr => false, 

source_database => 'ciscosys', 

inclusion_rule => true); 

end; 

3.12 启动STREAM 

#strmadmin身份,登录从数据库。 

connect strmadmin/strmadmin 

 

#启动Apply进程 

begin 

dbms_apply_adm.start_apply( 

apply_name => 'apply_book'); 

end; 

 

#strmadmin身份,登录主数据库。 

connect strmadmin/strmadmin 

 

#启动Capture进程 

begin 

dbms_capture_adm.start_capture( 

capture_name => 'capture_ciscosys'); 

end; 

3.13 停止STREAM 

#strmadmin身份,登录主数据库。 

connect strmadmin/strmadmin 

 

#停止Capture进程 

begin 

dbms_capture_adm.stop_capture( 

capture_name => 'capture_ciscosys'); 

end; 

 

#strmadmin身份,登录从数据库。 

connect strmadmin/strmadmin 

 

#停止Apply进程 

begin 

dbms_apply_adm.stop_apply( 

apply_name => 'apply_book'); 

end; 

 

4 测试场景 

    本文档建立了针对hr用户的Stream 复制环境,如果没有特别声明,以下测试场景均以hr用户身份执行。 

4.1 建一张表测试 

主数据库 

SQL> CREATE TABLE aaa(id NUMBER PRIMARY KEY, name VARCHAR2(50)) 

4 / 

Table created. 

 

从数据库 

SQL> desc TTT 

Name Null? Type 

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

ID NOT NULL NUMBER 

NAME VARCHAR2(50) 

4.2 表中插入一行数据 

主数据库 

SQL> insert into aaa values (1,'sdfsdfsdfsdf'); 

1 row created. 

SQL> commit; 

Commit complete. 

 

SQL> 

从数据库 

SQL> select * from aaa; 

ID NAME 

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

1 sdfsdfsdfsdf 

5 问题诊断 

5.1 如何知道捕捉(Capture)进程是否运行正常? 

strmadmin身份,登录主数据库,执行如下语句: 

SQL> SELECT CAPTURE_NAME,  QUEUE_NAME,  RULE_SET_NAME,     NEGATIVE_RULE_SET_NAME,  STATUS  FROM DBA_CAPTURE;  

结果显示如下: 

CAPTURE_NAME QUEUE_NAME 

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

RULE_SET_NAME NEGATIVE_RULE_SET_NAME STATUS 

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

CAPTURE_PROD PROD_QUEUE 

RULESET$_14 ENABLED 

ENABLED 

 

如果STATUS状态是ENABLED,表示Capture进程运行正常; 

如果STATUS状态是DISABLED,表示Capture进程处于停止状态,只需重新启动即可; 

如果STATUS状态是ABORTED,表示Capture进程非正常停止,查询相应的ERROR_NUMBERERROR_MESSAGE列可以得到详细的信息;同时,Oracle会在跟踪文件中记录该信息。 

5.2 如何知道Captured LCR是否有传播GAP 

strmadmin身份,登录主数据库,执行如下语句: 

SQL> SELECT CAPTURE_NAME, QUEUE_NAME, STATUS, CAPTURED_SCN, APPLIED_SCN  FROM DBA_CAPTURE; 

 

结果显示如下: 

CAPTURE_NAME QUEUE_NAME STATUS 

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

CAPTURED_SCN APPLIED_SCN 

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

CAPTURE_PROD PROD_QUEUE ENABLED 

17023672 17023672 

 

如果APPLIED_SCN小于CAPTURED_SCN,则表示在主数据库一端,要么LCR没有被dequeue,要么Propagation进程尚未传播到从数据库一端。 

5.3 如何知道Appy进程是否运行正常? 

strmadmin身份,登录从数据库,执行如下语句: 

SQL> SELECT apply_name, apply_captured, status FROM dba_apply; 

 

结果显示如下: 

APPLY_NAME APPLY_ STATUS 

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

APPLY_H10G YES ENABLED 

如果STATUS状态是ENABLED,表示Apply进程运行正常; 

如果STATUS状态是DISABLED,表示Apply进程处于停止状态,只需重新启动即可; 

如果STATUS状态是ABORTED,表示Apply进程非正常停止,查询相应的ERROR_NUMBERERROR_MESSAGE列可以得到详细的信息;同时,可以查询DBA_APPLY_ERROR视图,了解详细的Apply错误信息。 

 

 

6 结篇 

    通过如上的测试可以看出stream的功能还是十分强大的,通过配置Oracle Stream可以更大的提升数据库的可用性和安全,如此一个好用且不用花费高昂额外费用的功能还是很值得一用的。

清除所有配置信息 

要清楚Stream配置信息,需要先执行3.13,停止Stream进程。 

 

#strmadmin身份,登录主数据库。 

connect strmadmin/strmadmin 

exec DBMS_STREAMS_ADM.remove_streams_configuration(); 

 

#strmadmin身份,登录从数据库。 

connect strmadmin/strmadmin 

exec DBMS_STREAMS_ADM.remove_streams_configuration();

 

 

Q:如果高级复制环境中的主体定义站点损坏,如何将主体定义站点切换到另外的主体站点上?
A
:分为两种情况。备注:每次运行完repcat包以后都应该执行一次commit,因为某些rep的存储过程是不会自动commit的,同时这也是一个troubleshooting,一般的rep脚本都会较快的返回结果,如果一条命令之后长时间没有结果返回,那么很可能是上面的命令没有commit,取消掉当前的命令,然后作一次commit,再重新执行,一般都能够解决问题。一是只有主体定义站点损坏。假设站点A是主体定义站点,已经损坏,在复制环境中还有站点B,想作为新的主体定义站点。
1
.以repadmin身份登录站点B,执行主体站点切换。
connect repadmin/repadmin
execute dbms_repcat.relocate_masterdef
(gname =>'repg',
old_masterdef =>'shenzhen.test.com.cn',
new_masterdef =>'beijing.test.com.cn',
notify_masters =>true,
include_old_masterdef =>false);

2
.将站点A作为主体站点删除
execute dbms_repcat.remove_master_databases
(gname =>'repg',
master_list =>'shenzhen.test.com.cn');

3
.当站点A重新可用时,用repadmin用户登录站点A,删除其中的复制组信息
connect repadmin/repadmin
execute dbms_repcat.drop_master_repgroup
(gname =>'repg',
drop_contents =>true,
all_sites => false);
如果要使站点A重新称为复制环境中的一个主体站点,继续执行下面的45两步,否则切换主体定义站点就已经完成了。
4
登录站点B(新的主体定义站点)
connect repadmin/repadmin

execute dbms_repcat.suspend_master_activity
(gname =>'repg')

execute dbms_repcat.add_master_database
(gname => 'repg',
master =>'shenzhen.test.com.cn',
use_existing_objects =>true,
copy_rows =>false);

5
.重新开始复制
execute dbms_repcat.resume_master_activity
(gname =>'repg',true)
第二种情况是一些主体站点和主体定义站点同时损坏了。
1
.依次登录所有正常运行的主体站点,执行主体定义站点切换
execute dbms_repcat.relocate_masterdef
(sname =>; 'schemaname',
old_masterdef =>; 'oldmaster.world',
new_masterdef =>; 'newmaster.world',
notify_masters =>; false, /*
此处是false,而第一种情况中这个参数是true */
include_old_masterdef =>; false);
后面的操作步骤跟情况一相同,依次执行25就可以了

 

这是一个同步复制环境,在同步复制中,任何一个站点Down掉都会导致数据库服务中断。

1.
停掉主体定义站点(CONNER.HURRAY.COM.CN)

[oracle@jumper oracle]$ sqlplus "/ as sysdba"

 

SQL*Plus: Release 9.2.0.4.0 - Production on Thu Feb 17 16:07:26 2005

 

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

 

 

Connected to:

Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production

With the Partitioning option

JServer Release 9.2.0.4.0 - Production

 

SQL> shutdown immediate;

Database closed.

Database dismounted.

ORACLE instance shut down.

 

2.登陆主体站点(TESTORA9.HURRAY.COM.CN)

SQL> select * from dept;

 

    DEPTNO DNAME          LOC

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

        10 ACCOUNTING     NEW YORK

        20 RESEARCH       DALLAS

        30 SALES          CHICAGO

        40 OPERATIONS     BOSTON

        60 ORACLE         BEIJING

        70 oracle         beijing

 

6 rows selected.


此时主体站点上对于扶植对象的任何DML操作都不能进行了。

SQL> insert into dept values(80,'oracle','beijing');

insert into dept values(80,'oracle','beijing')

*

ERROR at line 1:

ORA-02068: following severe error from CONNER

ORA-03113: end-of-file on communication channel

ORA-02068: following severe error from CONNER

ORA-03113: end-of-file on communication channel


3.
使用复制管理员登陆主体站点

如果此时尝试删除复制对象,打破复制关系都会收到错误。
ORA-23312
说明这不是主体定义站点。

SQL> connect repadmin/repadmin                                                               

Connected.

SQL> exec DBMS_REPCAT.DROP_MASTER_REPOBJECT(sname => 'scott',oname => 'dept',type => 'table');

BEGIN DBMS_REPCAT.DROP_MASTER_REPOBJECT(sname => 'scott',oname => 'dept',type => 'table'); END;

 

*

ERROR at line 1:

ORA-23312: not the masterdef according to TESTORA9.HURRAY.COM.CN

ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86

ORA-06512: at "SYS.DBMS_REPCAT_UTL4", line 2928

ORA-06512: at "SYS.DBMS_REPCAT_UTL4", line 2720

ORA-06512: at "SYS.DBMS_REPCAT", line 643

ORA-06512: at line 1


4.
使用DBMS_REPCAT.RELOCATE_MASTERDEF切换主体定义站点

SQL> BEGIN

  2  DBMS_REPCAT.RELOCATE_MASTERDEF (

  3        gname => 'rep_tt',

  4        old_masterdef => 'CONNER.HURRAY.COM.CN',

  5        new_masterdef => 'TESTORA9.HURRAY.COM.CN',

  6        notify_masters => TRUE,

  7        include_old_masterdef => FALSE);

  8  END;

  9  /

 

PL/SQL procedure successfully completed.


5.
把原主体定义站点(CONNER.HURRAY.COM.CN)从主体库中删除

SQL> execute dbms_repcat.remove_master_databases(gname=>'rep_tt',master_list=>'CONNER.HURRAY.COM.CN');

 

PL/SQL procedure successfully completed.


6.
复制关系打破以后,DML操作得以继续

SQL> connect scott/tiger

Connected.

SQL> select * from dept;

 

    DEPTNO DNAME          LOC

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

        10 ACCOUNTING     NEW YORK

        20 RESEARCH       DALLAS

        30 SALES          CHICAGO

        40 OPERATIONS     BOSTON

        60 ORACLE         BEIJING

        70 oracle         beijing

 

6 rows selected.

 

SQL> insert into dept values (80,'oracle','beijing');

 

1 row created.

 

SQL> commit;

 

Commit complete.

 

SQL>


7.
如果原站点恢复正常后,可以再次添加到复制组中