ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 一步一步配置Oracle Stream

一步一步配置Oracle Stream

原创 Linux操作系统 作者:fengjin821 时间:2009-06-10 15:09:57 0 删除 编辑

一步一步配置Oracle Stream

 

1 引言
    Oracle Stream
功能是为提高数据库的高可用性而设计的,在Oracle 9i及之前的版本这个功能被称为Advance ReplicationOracle Stream利用高级队列技术,通过解析归档日志,将归档日志解析成DDLDML语句,从而实现数据库之间的同步。这种技术可以将整个数据库、数据库中的对象复制到另一数据库中,通过使用Stream的技术,对归档日志的挖掘,可以在对主系统没有任何压力的情况下,实现对数据库对象级甚至整个数据库的同步。


   
解析归档日志这种技术现在应用的比较广泛,Quest公司的shareplex软件及DSG公司的realsync都是这样的产品,一些公司利用这样的产品做应用级的容灾。但shareplex或是realsync都是十分昂贵的,因此你可以尝试用Stream这个Oracle提供的不用额外花钱的功能。Oracle Stream对生产库的影响是非常小的,从库可以是与主库不同的操作系统平台,你可以利用Oracle Stream复制几个从库,从库可用于查询、报表、容灾等不同的功能。本文不谈技术细节,只是以手把手的方式一步一步的带你把Stream的环境搭建起来,细节内容可以查联机文档。


2
概述

主数据库:


操作系统:
Solaris 9
IP
地址:
192.168.10.35
数据库:
Oracle 10.2.0.2
ORACLE_SID
prod
Global_name
prod

从数据库:

操作系统:
AIX 5.2
IP
地址:
192.168.10.43
数据库:
Oracle 10.2.0.3
ORACLE_SID
h10g
Global_name
h10g

 

3 环境准备
3.1
设定初始化参数

使用pfile的修改init.ora文件,使用spfile的通过alter system命令修改spile文件。主、从数据库分别执行如下的语句:

Sqlplus ‘/ as sysdba’
alter system set aq_tm_processes=2 scope=both;
alter system set global_names=true scope=both;
alter system set job_queue_processes=10 scope=both;
alter system set parallel_max_servers=20 scope=both;
alter system set undo_retention=3600 scope=both;
alter system set nls_date_format='YYYY-MM-DD HH24:MI:SS' scope=spfile;
alter system set streams_pool_size=25M scope=spfile;
alter system set utl_file_dir='*' scope=spfile;
alter system set open_links=4 scope=spfile;

执行完毕后重启数据库。

3.2
将数据库置为归档模式

设置log_archive_dest_1到相应的位置;设定log_archive_startTRUE,即启用自动归档功能;设定log_archive_format指定归档日志的命令格式。

举例:

sqlplus ‘/ as sysdba’
alter system set log_archive_dest_1=’location=/yang/arch’ scope=spfile;
alter system set log_archive_start=TRUE scope=spfile;
alter system set log_archive_format=’ arch%t_%s_%r.arc’ scope=spfile;
shutdown immediate;
startup mount;
alter database archivelog;
alter database open;

数据库置为归档模式后,可以按如下方式检验一下:

SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination /yang/arch
Oldest online log sequence 534
Next log sequence to archive 536
Current log sequence 536

观注标红的部分。


3.3
创建stream 管理用户

3.3.1
创建主环境stream管理用户

#
sysdba身份登录

connect / as sysdba

#
创建主环境的Stream专用表空间

create tablespace tbs_stream datafile '/yang/oradata/prod/tbs_stream01.dbf'
size 100m autoextend on maxsize unlimited segment space management auto;

#
logminer的数据字典从system表空间转移到新建的表空间,防止撑满system表空间

execute dbms_logmnr_d.set_tablespace('tbs_stream');

#
创建Stream管理用户

create user strmadmin identified by strmadmin
default tablespace tbs_stream temporary tablespace temp;

#
授权Stream管理用户

grant connect,resource,dba,aq_administrator_role to strmadmin;

begin
dbms_streams_auth.grant_admin_privilege(
grantee => 'strmadmin',
grant_privileges => true);
end;
/
3.3.2
创建从环境stream管理用户

#
sysdba身份登录

connect / as sysdba

#
创建Stream专用表空间,我的从库用了ASM,这一步也可以参见
3.3.1
create tablespace tbs_stream datafile '+VGDATA/h10g/datafile/tbs_stream01.dbf'
size 100m autoextend on maxsize unlimited segment space management auto;
#
同样,将logminer的数据字典从system表空间转移到新建的表空间,防止撑满system表空间

execute dbms_logmnr_d.set_tablespace('tbs_stream');

#
创建Stream管理用户

create user strmadmin identified by strmadmin
default tablespace tbs_stream temporary tablespace temp;

#
授权Stream管理用户

grant connect,resource,dba,aq_administrator_role to strmadmin;

begin
dbms_streams_auth.grant_admin_privilege(
grantee => 'strmadmin',
grant_privileges => true);
end;
/

3.4
配置网络连接

3.4.1
配置主环境
tnsnames.ora
主数据库(tnsnames.ora)中添加从数据库的配置。

H10G =
(DE  script  ION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.10.43)(PORT = 1521))
)
(CONNECT_DATA =
(SID = h10g)
(SERVER = DEDICATED)
)
)
3.4.2
配置从环境
tnsnames.ora
从数据库(tnsnames.ora)中添加主数据库的配置。

PROD =
(DE  script  ION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.10.35)(PORT = 1521))
)
(CONNECT_DATA =
(SID = prod)
(SERVER = DEDICATED)
)
)
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.6
创建
DBlink
根据Oracle 10gR2 Stream官方文档,针对主数据库建立的数据库链的名字必须和从数据库的global_name相同。

如果需要修改global_name,执行“alter database rename global_name to xxx”

3.6.1
创建主数据库数据库链

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

connect strmadmin/strmadmin
#
建立数据库链

create database link h10g connect to strmadmin identified by strmadmin using 'h10g';
3.6.2
创建从数据库数据库链

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

connect strmadmin/strmadmin
#
建立数据库链

create database link prod connect to strmadmin identified by strmadmin using 'prod';
3.7
创建流队列

3.7.1
创建Master流队列

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

connect strmadmin/strmadmin

begin
dbms_streams_adm.set_up_queue(
queue_table => 'prod_queue_table',
queue_name => 'prod_queue');
end;
/
3.7.2
创建Backup流队列

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

connect strmadmin/strmadmin

begin
dbms_streams_adm.set_up_queue(
queue_table => 'h10g_queue_table',
queue_name => 'h10g_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_prod',
queue_name => 'strmadmin.prod_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@prod file='/tmp/hr.dmp' object_consistent=y rows=y

imp userid=system/manager@h10g file='/tmp/hr.dmp' ignore=y commit=y log='/tmp/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 => 'prod_to_h10g',
source_queue_name => 'strmadmin.prod_queue',
destination_queue_name => 'strmadmin.h10g_queue@h10g',
include_dml => true,
include_ddl => true,
include_tagged_lcr => false,
source_database => 'prod',
inclusion_rule => true);
end;
/

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

begin
dbms_aqadm.alter_propagation_schedule(
queue_name => 'prod_queue',
destination => 'h10g',
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_h10g',
queue_name => 'strmadmin.h10g_queue',
include_dml => true,
include_ddl => true,
include_tagged_lcr => false,
source_database => 'prod',
inclusion_rule => true);
end;
/
3.12
启动
STREAM
#
strmadmin身份,登录从数据库。

connect strmadmin/strmadmin

#
启动Apply进程

begin
dbms_apply_adm.start_apply(
apply_name => 'apply_h10g');
end;
/

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

connect strmadmin/strmadmin

#
启动Capture进程

begin
dbms_capture_adm.start_capture(
capture_name => 'capture_prod');
end;
/
3.13
停止
STREAM
#
strmadmin身份,登录主数据库。

connect strmadmin/strmadmin

#
停止Capture进程

begin
dbms_capture_adm.stop_capture(
capture_name => 'capture_prod');
end;
/

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

connect strmadmin/strmadmin

#
停止Apply进程

begin
dbms_apply_adm.stop_apply(
apply_name => 'apply_h10g');
end;
/
3.14
清除所有配置信息

要清楚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();

 

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

4.1
建一张表测试

主数据库

SQL> CREATE TABLE TTT(id NUMBER PRIMARY KEY,
2 name VARCHAR2(50)
3 )
4 /

Table created.

从数据库

SQL> desc TTT
Name Null? Type
---------- -------- -------------
ID NOT NULL NUMBER
NAME VARCHAR2(50)
4.2
表中插入一行数据

主数据库

SQL> insert into ttt values (1,'sdfsdfsdfsdf');
1 row created.
SQL> commit;
Commit complete.

SQL>
从数据库

SQL> select * from TTT;
ID NAME
---------- --------------------
1 sdfsdfsdfsdf
4.3
变更一下表的结构,添加一列

主数据库

SQL> ALTER TABLE TTT ADD(age NUMBER(2));
Table altered

从数据库

SQL> desc TTT
Name Null? Type
----------- -------- --------------
ID NOT NULL NUMBER
NAME VARCHAR2(50)
AGE NUMBER(2)
4.4
将表换一个表空间

主数据库

SQL> SELECT table_name,tablespace_name FROM user_tables
2
  
WHERE table_name='TTT';

TABLE_NAME TABLESPACE_NAME
------------------------------ ------------------------------
TTT USERS

SQL> ALTER TABLE TTT MOVE TABLESPACE tbs_stream;
Table altered

SQL> SELECT table_name,tablespace_name FROM user_tables
  
WHERE table_name='TTT';
TABLE_NAME TABLESPACE_NAME
------------------------------ ------------------------------
TTT TBS_STREAM

从数据库

SQL> SELECT table_name,tablespace_name FROM user_tables
  
WHERE table_name='TTT';
TABLE_NAME TABLESPACE_NAME
------------------------------ ------------------------------
TTT TBS_STREAM
4.5
表上Name列建一索引

主数据库

SQL> CREATE INDEX ttt_name_idx ON TTT(name);
Index created

从数据库

SQL> SELECT table_name, index_name FROM user_indexes WHERE table_name = 'TTT';
TABLE_NAME INDEX_NAME
------------------------------
    
------------------------------
TTT TTT_NAME_IDX
TTT SYS_C005721

4.6 Rebuild
索引测试

主数据库

SQL> ALTER INDEX ttt_name_idx REBUILD;
Index altered

从数据库

SQL> SELECT table_name, index_name FROM user_indexes WHERE table_name = 'TTT';
TABLE_NAME INDEX_NAME
------------------------------
    
------------------------------
TTT TTT_NAME_IDX
TTT SYS_C005721

4.7
索引换一个表空间测试

主数据库

SQL> ALTER INDEX ttt_name_idx REBUILD TABLESPACE tbs_stream;
Index altered

从数据库

SQL> SELECT table_name,index_name,tablespace_name FROM user_indexes
  
WHERE table_name = 'TTT';

TABLE_NAME INDEX_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
TTT TTT_NAME_IDX TBS_STREAM
TTT SYS_C005721 USERS

4.8
删除索引测试

主数据库

SQL> DROP INDEX ttt_name_idx;
Index dropped

从数据库

SQL> SELECT table_name,index_name,tablespace_name FROM user_indexes
  
WHERE table_name = ‘TTT’;

TABLE_NAME INDEX_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
TTT SYS_C005721 USERS
4.9
删除表测试

主数据库

SQL> DROP TABLE ttt;
Table dropped

从数据库

SQL> DESC ttt;
Object ttt does not exist.

4.10
建一张带有LOB类型字段的表测试

主数据库

SQL> CREATE TABLE tttclob(id NUMBER PRIMARY KEY, memo CLOB);
Table created

从数据库

SQL> DESC tttclob;
Name Null? Type
----------- -------- --------------
ID NOT NULL NUMBER
MEMO CLOB

4.11
表中插入一行数据

主数据库

SQL> INSERT INTO tttclob VALUES(1,'clob_test');
1 row inserted
SQL> commit;
Commit complete

从数据库

SQL> SELECT * FROM tttclob;

ID MEMO
---------- --------------------------------------------------------------------------------
1 clob_test

4.12
创建Type测试

主数据库

SQL> CREATE or REPLACE TYPE ttttype;
2 /
Type created

从数据库

SQL> SELECT * FROM user_types WHERE type_name='TTTTYPE';
TYPE_NAME TYPE_OID TYPECODE ATTRIBUTES METHODS PREDEFINED INCOMPLETE FINAL INSTANTIABLE SUPERTYPE_OWNER SUPERTYPE_NAME LOCAL_ATTRIBUTES LOCAL_METHODS TYPEID
------------------------------ -------------------------------- ------------------------------ ---------- ---------- ---------- ---------- ----- ------------ ------------------------------ ------------------------------ ---------------- ------------- --------------------------------
TTTTYPE 1B36AAF10DA8301DE040A8C0289A77B4 OBJECT 0 0 NO YES YES YES

4.13
删除Type测试

主数据库

SQL> DROP TYPE ttttype;
Type dropped

从数据库

SQL> SELECT * FROM user_types WHERE type_name='TTTTYPE';
TYPE_NAME TYPE_OID TYPECODE ATTRIBUTES METHODS PREDEFINED INCOMPLETE FINAL INSTANTIABLE SUPERTYPE_OWNER SUPERTYPE_NAME LOCAL_ATTRIBUTES LOCAL_METHODS TYPEID
------------------------------ --------------------------------

 

 

5 问题诊断
5.1
如何知道捕捉(Capture)进程是否运行正常?

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

SQL> SELECT CAPTURE_NAME,
2 QUEUE_NAME,
3 RULE_SET_NAME,
4
    
NEGATIVE_RULE_SET_NAME,
5 STATUS
6 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
2 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可以更大的提升数据库的可用性和安全性,如此一个好用且不用花费高昂额外费用的功能还是很值得一用的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13165828/viewspace-605811/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2009-04-29

  • 博文量
    191
  • 访问量
    507665