Oracle Stream--Oracle两数据库同步 《转载》

   Oracle官方网:
 

    Oracle Stream功能是为提高数据库的高可用性而设计的,在Oracle 9i及之前的版本这个功能被称为Advance Replication。Oracle Stream利用高级队列技术,通过解析归档日志,将归档日志解析成DDL及DML语句,从而实现数据库之间的同步。这种技术可以将整个数据库、数据库中的对象复制到另一数据库中,通过使用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<SID>.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_start为TRUE,即启用自动归档功能;设定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 = 
(DESCRIPTION = 
(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 = 
(DESCRIPTION = 
(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 
------------------------------ -------------------------------- -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值