------本文摘自 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_NUMBER、ERROR_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_NUMBER、ERROR_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重新称为复制环境中的一个主体站点,继续执行下面的4,5两步,否则切换主体定义站点就已经完成了。
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);
后面的操作步骤跟情况一相同,依次执行2-5就可以了
这是一个同步复制环境,在同步复制中,任何一个站点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.如果原站点恢复正常后,可以再次添加到复制组中