stream手札

STREAM配置手札

     

stream 介绍

Oracle从9i开始推出streams,用于提供灵活的复制和容灾解决方案。但是9i的streams配置相当的麻烦,少说也有十几个步骤,还容易出错。10gR2则将整个配置过程封装在几个简单的PL/SQL过程中,使得配置过程大大的简化。但是实际的配置步骤还是一样的,Oracle只是利用这些PL/SQL过程先生成对应的脚本,然后再执行脚本进行配置。这个过程可以全自动完成,也可以先将脚本生成到某个指定的目录,我们根据需要修改脚本,然后再执行脚本进行配置,这样就灵活又方便。

Streams的原理其实很简单,通过logmnr技术从oracle的log中解析出数据,然后传递到目标库并应用,从而将源库的数据复制到目标库。当然,复制可以是双向的,也可以是单向的。双向复制还需要考虑数据冲突的问题。而多源复制其实是双向复制的基础上衍生而来的。

整个的复制过程可以分成三个步骤:捕获(capture),传播(propagation)和应用(apply),利用高级队列(advance queue)来将这三个步骤的数据串起来,通过在步骤中定义不同的规则(rule)来控制需要复制的数据。复制可以基于全库,基于表空间,基于用户或者基于表,提供了相当大的灵活性。

捕获进程可以直接在源库捕获日志,也可以先将日志(归档日志或者联机日志)传递另外的库中进行捕获,这就是本地捕获(local capture)和异地捕获(downstream capture)。对于异地捕获,根据是传递归档日志还是联机日志,可以分为普通的异地捕获和实时异地捕获。日志的传递其实和DataGuard中是一样的机制。Oracle11g的streams还提供了同步捕获,这里暂时不涉及了。

描述一下复制的简单过程如下:

首先捕获进程从日志解析出数据,封装在一个个的逻辑改变记录(LCR:logical change record)中,将这些lcr压进捕获队列中,然后传播进程从捕获队列取得数据压进应用队列中,最后应用进程从应用队列取得LCR并应用到目标库中。LCR可以分为row LCR(DML操作记录)和DDL LCR(DDL操作记录),所以streams复制可以支持DDL操作的复制。

Streams复制需要先进行一次初始化建立基线,然后在此基础上复制增量数据。对于全库的初始化,可以使用RMAN。表空间复制的初始化可以使用transport tablespace,而对于用户复制和表复制,则可以使用exp/imp或者expdb/impdp。

Streams配置和管理相关package

dbms_steams_adm
dbms_capture_adm
dbms_propagation_adm
dbms_apply_adm
dbms_rule_adm

Streams主要相关数据字典

dba_streams_administrator

dba_capture
dba_capture_parameters

dba_propagation
dba_registered_archived_log

dba_apply
dba_apply_confict_columns
dba_apply_dml_handlers
dba_apply_enqueue
dba_apply_error
dba_apply_execute
dba_apply_parameters
dba_apply_progress

dba_rules
dba_rule_sets
dba_rule_set_rules

V$STREAMS_CAPTURE
V$STREAMS_POOL_ADVICE
V$STREAMS_TRANSACTION

V$PROPAGATION_RECEIVER
V$PROPAGATION_SENDER

V$STREAMS_APPLY_COORDINATOR
V$STREAMS_APPLY_READER
V$STREAMS_APPLY_SERVER

更多streams数据字典,请参考这里

Streams涉及到很多的概念,本文只是提到了其中很少一部分,要想深入的了解streams机制和实现,请参考Oracle的两本官方文档:
Streams Concepts and Administration
Streams Replication Administrator’s Guide

2 配置

简单说一下环境:oracle 11.2.0.2 linux 64bit

源库:10.2.2.20 sid:ccxgather/10.2.2.18 sid:demo18

目标库:10.2.2.16 sid:quality

2.1 检查系统参数

--检查以下参数,其实除第一个外其他在11g采用默认值即可

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;
--downstream不需要

alter system set utl_file_dir='*' scope=spfile;

--11.2默认为4
alter system set open_links=4 scope=spfile;

2.2 检查主键

10.2.2.20(源库)

select t.table_name,c.index_name,c.constraint_type from

(select * From dba_tables where owner='owner1') t left join

(select * from dba_constraints where owner='owner1' and constraint_type='P') c

on t.table_name=c.table_name

where c.index_name is null

 

2.3创建streamadmin用户

10.2.2.16上:

CREATE TABLESPACE streams_tbs DATAFILE '/data/quality/streams_tbs.dbf' SIZE 100M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;

create user username identified by "Password" default tablespace streams_tbs;

grant dba to username;

begin

exec DBMS_STREAMS_AUTH.GRANT_ADMIN_PRIVILEGE('stradmin');

end;

 

10.2.2.20上:

CREATE TABLESPACE streams_tbs DATAFILE '/data/oradata/progather/streams_01.dbf' SIZE 100M

REUSE AUTOEXTEND ON next 100M MAXSIZE 8192M;

create user username identified by "password" default tablespace streams_tbs;

grant dba to username;

begin

exec DBMS_STREAMS_AUTH.GRANT_ADMIN_PRIVILEGE('username');

end;

2.4 建立dblink

10.2.2.20

create database link quality connect to usernameidentified by pasword using '16';

--测试一下

select * from global_name@stream

10.2.2.16

create database link progathe connect to username identified by password using '20';

2.5 建立复制目录异地捕获表级不需要

 源库 10.2.2.18

create directory dir_source_01 as '/data/source/'

10.2.2.20

create directory stream_01 as '/data/oradata/progather/'

2.6 将日志传送至目标库

源库上执行

--追加尾日志

alter database add supplemental log data;

alter system set log_archive_config=’dg_config=(demo18,quality)’

alter system set log_archive_dest_2 ='service=quality arch noregister db_unique_name=quality';

说明:生成密码文件

orapwd

目标库上执行:

alter system set log_archive_config=’dg_config=(demo18,quality)’

 

2.7 执行dbms_streams_adm包中的maintain_

2.7.1--建立表空间级复制

declare

v_ts dbms_streams_tablespace_adm.tablespace_set;

begin

v_ts(1) := 'tablespacesname';

dbms_streams_adm.maintain_tts(

tablespace_names => v_ts,

source_directory_object => 'stream_20',

destination_directory_object => 'stream_16',

source_database => 'stream20',

destination_database => 'stream16',

perform_actions => true,

include_ddl => true);

end;

  • MAINTAIN_SIMPLE_TTS :单个表空间的复制
  • MAINTAIN_TTS :多个表空间的复制
  • PRE_INSTANTIATION_SETUP POST_INSTANTIATION_SETUP:多个表空间的复制

--检查是不否有自包含

SQL> exec sys.dbms_tts.transport_set_check('owner',true,true);

 

PL/SQL procedure successfully completed

 

SQL> select * from sys.transport_set_violations;

select * from dba_apply;
select * from dba_apply_error;

2.7.2 多表复制

先将表exp源库再imp到目标库

exp demo/demo@demo18 file=demo.dmp

imp demo/demo@quality file=demo.dmp

declare

v_tables dbms_utility.uncl_array;

begin

v_tables(1) := DEMO.BOND_ASE_PLAN';

dbms_streams_adm.maintain_tables(

table_names => v_tables,

source_directory_object => NULL,

destination_directory_object => NULL,

source_database => 'demo18',

destination_database => 'quality',

perform_actions => true,

bi_directional => false,

include_ddl => true,

instantiation => dbms_streams_adm.instantiation_table_network);

end;

/

说明:在源库执行maintain_tables,目标库几乎什么都不用做,stream环境已经配置好啦,

如果想复制其它的表,只用再执行maintain_tables过程即可,其实他是封装了以前9i的步骤

.可以从DBA_RECOVERABLE_SCRIPT_BLOCKS查出详细步骤

2.7.3 shema级复制

BEGIN

DBMS_STREAMS_ADM.MAINTAIN_SCHEMAS(

schema_names =>'OWNER',

source_directory_object => 'DIR_SOURCE',

destination_directory_object => 'DIR_DEST',

source_database => 'DEMO18',

destination_database => 'QUALITY',

perform_actions => true,

dump_file_name => NULL,

log_file => NULL,

bi_directional => NULL,

include_ddl => true,

instantiation => DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA);

END;

  • DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA :通过expdp/impdp初始化数据,并在目标端导入数据时执行实例化,默认情况下即是该值。
  • DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA_NETWORK :impdp直接通过网络传输数据而不生成dmp文件。在导入数据时执行实例化。
  • DBMS_STREAMS_ADM.INSTANTIATION_NONE :不执行实例化,该属性值仅当perform_actions参数设置为false时有效。

不过这里有个很不可思议的事情,如果dumpimp过程中出错了,从字典视图取不到任何记录,只能看dump_dest目录下的dlg文件。至于怎么清除这个job,暂时没办法。

3相关错误

3.1错误字典

DBA_RECOVERABLE_SCRIPT:配置脚本概要信息
DBA_RECOVERABLE_SCRIPT_PARAMS:配置脚本参数
DBA_RECOVERABLE_SCRIPT_ERRORS:执行过程中的错误信息
DBA_RECOVERABLE_SCRIPT_BLOCKS:配置脚本的详细步骤

Eg:

执行一个表复制时报这个错:

 

ORA-23616: Failure in executing block 2 for script AE0FA65415C205D6E040007F010066A8 with

ORA-20099: SORRY,YOU CAN NOT EXECUTE THE COMMAND. PLEASE CONTACT THE DBA

ORA-06512: at "SYS.DBMS_RECO_SCRIPT_INVOK", line 139

--取出错误步骤

select * from dba_recoverable_script where script_id='AE0FA65415C205D6E040007F010066A8'

select * from dba_recoverable_script_blocks where script_id='AE0FA65415C205D6E040007F010066A8'

and block_num=1

--看错误详细信息

select * from dba_recoverable_script_errors where script_id='AE0FA65415C205D6E040007F010066A8'

and block_num=1

 

ORA-20099: SORRY,YOU CAN NOT EXECUTE THE COMMAND. PLEASE CONTACT THE DBA

ORA-06512: at "SYS.DBMS_RECO_SCRIPT_INVOK", line 139

ORA-06512: at "SYS.DBMS_STREAMS_RPC", line 485

3.2 重新执行

begin

dbms_streams_adm.recover_operation(

script_id => 'D74179203F11445D8F3F3F77C0749A1D',

operation_mode => 'FORWARD');

end;

/

 

3.3如果错误比较严重,无法再继续进行配置,那么可以将已经完成的步骤回滚掉

 

begin

dbms_streams_adm.recover_operation(

script_id => 'D74179203F11445D8F3F3F77C0749A1D',

operation_mode => 'ROLLBACK');

end;

/

 

3.4 清除stream配置

 

begin

dbms_streams_adm.recover_operation(

script_id => 'D74179203F11445D8F3F3F77C0749A1D',

operation_mode => 'PURGE');

end;

/

查询并停止正在捕捉

select capture_name,status from dba_capture;

停止

SQL> exec dbms_capture_adm.stop_capture('STREAM20$CAP');

查询并停止propagation进程

select propagation_name,status from dba_propagation;

SQL> exec dbms_propagation_adm.stop_propagation('PROPAGATION$_4');

exec dbms_propagation_adm.drop_propagation('PROPAGATION$_4');

查询删除queue

SQL> select * from dba_queues where owner='STRADMIN'

SQL> exec dbms_streams_adm.remove_queue('DEMO18$APPQ');

PL/SQL procedure successfully completed

SQL> exec dbms_streams_adm.remove_queue('AQ$_DEMO18$APPQT_E');

 

PL/SQL procedure successfully completed

查询apply进程:

SQL> select apply_name,queue_name from dba_apply;

 

APPLY_NAME                     QUEUE_NAME

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

APPLY$_STREAM20_15             STREAM20$APPQ

exec dbms_apply_adm.stop_apply('APPLY$_STREAM20_15');

最后清除整个stream配置

exec dbms_streams_adm.remove_streams_configuration;

删除rule

SQL> exec dbms_rule_adm.drop_rule('BOND_ASE_PLAN12 ');

Drop ruleset

SQL> exec dbms_rule_adm.drop_rule_set('RULESET$_11');

3.5 scn不一致处理

select APPLY_NAME,LOCAL_TRANSACTION_ID,SOURCE_COMMIT_SCN,MESSAGE_NUMBER,ERROR_MESSAGE from dba_apply_error;

source_commit_scn:1205861453

26687 ORA-26687: no instantiation SCN provided for "DEMO"."BOND_ASE_PLAN" in source da    

 

--继续执行

BEGIN

 DBMS_APPLY_ADM.START_APPLY(apply_name => 'APPLY$_DEMO18_3');

 END;

--源库执行

begin

 DBMS_APPLY_ADM.set_table_instantiation_scn@quality(source_object_name => 'DEMO.BOND_ASE_PLAN',

 source_database_name => 'DEMO18',

 instantiation_scn => 1205861453);

 end;

--目标库上执行

BEGIN

 DBMS_APPLY_ADM.EXECUTE_ERROR(

 local_transaction_id => '9.30.10856',

 execute_as_user => FALSE,

 user_procedure => NULL);

END;

 

 

3.6高级复制中的ORA-23318 /ORA-23308

 

如果先创建表而后使用了alter table add primary key()添加pk,那么到后来就会报出上述的错误,必须使用:

create table test (a number primary key);

或者

alter table test add constraint......的形式。

posted on 2011-10-12 16:54 snowhill 阅读(746) 评论(0)  编辑 收藏 引用 所属分类: 数据库-oracle


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

公告

又一年...........

留言簿(3)

随笔分类(13)

文章分类(131)

文章档案(124)

c++

java

linux

oracle

常用软件

其他

网络配置

系统安全

音乐

搜索

最新评论

阅读排行榜