表级流复制基本操作
创建单源流复制数据库
源数据库
创建流复制管理员
CREATE USER STREAMADMIN
IDENTIFIED BY STREAMADMIN DEFAULT TABLESPACE USERS"
TEMPORARY TABLESPACE "TEMP"
ACCOUNT UNLOCK;
GRANT CONNENT TO STREAMADMIN ;
GRANT DBA TO STREAMADMIN ;
创建数据库链接
CREATE DATABASE LINK "DEST" --数据库链接名,必须在netca中配置过
CONNECT TO "STREAMADMIN" --目的数据库时复制管理员
IDENTIFIED BY "STREAMADMIN" --目的数据库时复制管理员密码
USING 'DEST' ; --目的数据库名,必须在netca中配置过
创建捕捉队列
dbms_streams_adm.set_up_queue(
queue_table => '"STREAMADMIN"."TEST$CAPQT"',
storage_clause => NULL,
queue_name => '"STREAMADMIN"."TEST$CAPQ"',
queue_user => '');
对要复制的表实例化准备
对所有要复制的表执行
DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(
table_name => 'rep.a'
supplemental_logging => 'keys'); --默认值为key,如果不指定,将采在所有相约束上启用附加日志
添加附加日志
ALTER TABLE "REP"."C" ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, FOREIGN KEY, UNIQUE INDEX) COLUMNS;
创建传送进程及传输规则
对所有的表执行
dbms_streams_adm.add_table_propagation_rules( --加入传送规则(自动创建传送进程)
table_name => '"REP"."A"', --传送表rep.A
streams_name => '', --
source_queue_name => '"STREAMADMIN"."TEST$CAPQ"', --捕捉队列(源)
destination_queue_name=>"STREAMADMIN"."TEST$APPQ"@DEST', --应用队列(目的)
include_dml => TRUE, --捕捉dml
include_ddl => TRUE, --捕捉dml
include_tagged_lcr => TRUE, --传输带标签的LCR????
source_database => 'SOURCE.REGRESS.RDBMS.DEV.US.ORACLE.COM', --源数据库
inclusion_rule => TRUE, --加入正规则集
and_condition => NULL, --
queue_to_queue => TURE); --10.2 以后为TURE
新目标数据库
创建流复制管理员
CREATE USER STREAMADMIN
IDENTIFIED BY STREAMADMIN DEFAULT TABLESPACE USERS"
TEMPORARY TABLESPACE "TEMP"
ACCOUNT UNLOCK;
GRANT CONNENT TO STREAMADMIN ;
GRANT DBA TO STREAMADMIN ;
创建应用队列
dbms_streams_adm.set_up_queue(
queue_table => '"STREAMADMIN"."TEST$APPQT"', --队列表??
storage_clause => NULL, --
queue_name => '"STREAMADMIN"."TEST$APPQ"', --队列名
queue_user => ''); --
创建应用进程及应用规则
dbms_streams_adm.add_table_rules( --创建应用规则(自动创建应用进程)
table_name => '"REP"."A"', --要应用的表
streams_type => 'APPLY', --类型
streams_name => '', --
queue_name => '"STREAMADMIN"."TEST$APPQ"', --应用队列名
include_dml => TRUE, --包括dml
include_ddl => TRUE --包括ddl
include_tagged_lcr => TRUE, --标签不为空也行
source_database => 'TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM', --源数据库
inclusion_rule => TRUE); --加入正规则集
从源数据库导入数据并实例化scn
使用imp数据时加入参数STREAMS_INSTANTIATION=Y
或者得到源数据库的当前scn
select dbms_flashback.get_system_change_number from dual;
DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(
source_object_name => 'rep.a',
source_database_name => ' TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM ',
instantiation_scn => 1234567); --scn号
设置标签 (多个应用时,结构复杂时需要)
dbms_apply_adm.alter_apply(
apply_name => apply_nm_dqt, --应用名称,在dba_apply_progress中查看
apply_tag => hextoraw(00)); --00为本机应用标签
添加一个新的目标节点
源数据库
加入数据库链接
CREATE DATABASE LINK "DEST" --数据库链接名,必须在netca中配置过
CONNECT TO "STREAMADMIN" --目的数据库时复制管理员
IDENTIFIED BY "STREAMADMIN" --目的数据库时复制管理员密码
USING 'DEST' ; --目的数据库名,必须在netca中配置过
对要复制的表实例化准备
对所有要复制的表执行
DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(
table_name => 'rep.a'
supplemental_logging => 'keys'); --默认值为key,如果不指定,将采在所有相约束上启用附加日志
创建传送进程及传输规则
对所有的表执行
dbms_streams_adm.add_table_propagation_rules( --加入传送规则(自动创建传送进程)
table_name => '"REP"."A"', --传送表rep.A
streams_name => '', --
source_queue_name => '"STREAMADMIN"."TEST$CAPQ"', --捕捉队列(源)
destination_queue_name=>"STREAMADMIN"."TEST$APPQ"@DEST', --应用队列(目的)
include_dml => TRUE, --捕捉dml
include_ddl => TRUE, --捕捉dml
include_tagged_lcr => TRUE, --传输带标签的LCR????
source_database => 'SOURCE.REGRESS.RDBMS.DEV.US.ORACLE.COM', --源数据库
inclusion_rule => TRUE, --
and_condition => NULL, --
queue_to_queue => TURE); --10.2 以后为TURE
新目标数据库
创建流复制管理员
CREATE USER STREAMADMIN
IDENTIFIED BY STREAMADMIN DEFAULT TABLESPACE USERS"
TEMPORARY TABLESPACE "TEMP"
ACCOUNT UNLOCK;
GRANT CONNENT TO STREAMADMIN ;
GRANT DBA TO STREAMADMIN ;
创建应用队列
dbms_streams_adm.set_up_queue(
queue_table => '"STREAMADMIN"."TEST$APPQT"', --队列表??
storage_clause => NULL, --
queue_name => '"STREAMADMIN"."TEST$APPQ"', --队列名
queue_user => ''); --
创建应用进程及应用规则
dbms_streams_adm.add_table_rules( --创建应用规则(自动创建应用进程)
table_name => '"REP"."A"', --要应用的表
streams_type => 'APPLY', --类型
streams_name => '', --
queue_name => '"STREAMADMIN"."TEST$APPQ"', --应用队列名
include_dml => TRUE, --包括dml
include_ddl => TRUE --包括ddl
include_tagged_lcr => TRUE, --标签不为空也行
source_database => 'TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM', --源数据库
inclusion_rule => TRUE); --创建并应用正规则集??
从源数据库导入数据并实例化scn
使用imp数据时加入参数STREAMS_INSTANTIATION=Y
或者得到源数据库的当前scn
select dbms_flashback.get_system_change_number from dual;
DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(
source_object_name => 'rep.a',
source_database_name => ' TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM ',
instantiation_scn => 1234567); --scn号
其他:
设置标签 –多个应用时,结构复杂时需要
dbms_apply_adm.alter_apply(
apply_name => apply_nm_dqt, --??
apply_tag => hextoraw(00));
添加一个新的复制表
源数据库
添加附加日志
ALTER TABLE "REP"."C" ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, FOREIGN KEY, UNIQUE INDEX) COLUMNS;
实例化准备
DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(
table_name => 'rep.c',
supplemental_logging => 'keys');
添加捕捉规则
dbms_streams_adm.add_table_rules(
table_name => '"REP"."C"',
streams_type => 'CAPTURE',
streams_name => '"TEST$CAP"',
queue_name => '"STREAMADMIN"."TEST$CAPQ"',
include_dml => TRUE,
include_ddl => TRUE,
include_tagged_lcr => TRUE,
source_database => 'TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM',
inclusion_rule => TRUE);
添加传送规则
dbms_streams_adm.add_table_propagation_rules(
table_name => '"REP"."C"',
streams_name => '',
source_queue_name => '"STREAMADMIN"."TEST$CAPQ"',
destination_queue_name => '"STREAMADMIN"."TEST$APPQ"@RMAN.REGRESS.RDBMS.DEV.US.ORACLE.COM',
include_dml => TRUE,
include_ddl => TRUE,
include_tagged_lcr => TRUE,
source_database => 'TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM',
inclusion_rule => TRUE,
and_condition => NULL,
queue_to_queue => TRUE);
目标数据库
导入对象并实例化
使用imp数据时加入参数STREAMS_INSTANTIATION=Y(生效)
或者得到源数据库的当前scn
select dbms_flashback.get_system_change_number from dual;
DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(
source_object_name => 'rep.c',
source_database_name => ' TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM ',
instantiation_scn => 1234567); --scn号
添加应用规则
dbms_streams_adm.add_table_rules(
table_name => '"REP"."C"',
streams_type => 'APPLY',
streams_name => '',
queue_name => '"STREAMADMIN"."TEST$APPQ"',
include_dml => TRUE,
include_ddl => TRUE,
include_tagged_lcr => TRUE,
source_database => 'TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM',
inclusion_rule => TRUE);
其他
搭建表级流复制系统代码
DECLARE
tables DBMS_UTILITY.UNCL_ARRAY;
BEGIN
tables(1) := 'rep.a'; --要复制的表名
tables(2) := 'rep.b'; --要复制的表名
DBMS_STREAMS_ADM.MAINTAIN_TABLES(
table_names => tables, --要复制的表对象集
source_directory_object => NULL,
destination_directory_object => NULL,
source_database => ' TEST ', --源数据库
destination_database => 'RMAN ', --目标数据库
perform_actions => false, --立即执行还是生成脚本
script_name => 'configure_rep.sql', --生成脚本的名称
script_directory_object => 'SCRIPT_DIRECTORY', --生成脚本的目录(由create directory .. as ..创建)
bi_directional => false, --是否使用多源复制
include_ddl => false, --是否包括DDL语句
instantiation => DBMS_STREAMS_ADM.INSTANTIATION_TABLE_NETWORK);
END;
/
启用/禁用捕捉进程
dbms_capture_adm.start_capture(
capture_name => '"TEST$CAP"');
dbms_capture_adm.stop_capture(
capture_name => '"TEST$CAP"');
启用/禁用传输
dbms_aqadm.enable_propagation_schedule(
queue_name => '"STREAMADMIN"."RMAN$CAPQ"',
destination => 'TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM',
destination_queue => '"STREAMADMIN"."RMAN$APPQ"');
dbms_aqadm.disable_propagation_schedule(
queue_name => '"STREAMADMIN"."TEST$CAPQ"',
destination => 'CHARGE.REGRESS.RDBMS.DEV.US.ORACLE.COM',
destination_queue => destn_q);
启用/禁用应用进程
dbms_apply_adm.start_apply(
apply_name => apply_nm_dqt);
dbms_apply_adm.stop_apply(
apply_name => apply_nm_dqt);
加入负规则集
(不传送本机应用标签的LCR)
dbms_streams_adm.add_table_propagation_rules(
table_name => '"REP"."A"',
streams_name => '',
source_queue_name => '"STREAMADMIN"."TEST$CAPQ"',
destination_queue_name => '"STREAMADMIN"."TEST$APPQ"@RMAN.REGRESS.RDBMS.DEV.US.ORACLE.COM',
include_dml => TRUE,
include_ddl => FALSE,
include_tagged_lcr => TRUE,
source_database => 'TEST.REGRESS.RDBMS.DEV.US.ORACLE.COM',
inclusion_rule => FALSE,
and_condition => ':lcr.get_tag() = HEXTORAW ("00") ', --00为本机应用进程的标签
queue_to_queue => true);
加入update冲突解决
DECLARE
cols DBMS_UTILITY.NAME_ARRAY;
BEGIN
cols(1) := 'c1'; --列名
cols(2) := 'c2'; --列名
DBMS_APPLY_ADM.SET_UPDATE_CONFLICT_HANDLER(
object_name => 'hr.jobs', --表名
method_name => 'OVERWRITE', --overwrite,discard,maximum,minmum,null
resolution_column => 'job_title', --
column_list => cols); --列集合
END;
/
自定义冲突解决
BEGIN
DBMS_APPLY_ADM.SET_DML_HANDLER(
object_name => 'hr.locations', --表名
object_type => 'TABLE', --
operation_name => 'UPDATE', --升级冲突
error_handler => false,
user_procedure => 'strmadmin.history_dml', --自定义存储过程 Null取消
apply_database_link => NULL,
apply_name => NULL);
END;
/
自定义存储过程
CREATE OR REPLACE PROCEDURE history_dml(in_any IN ANYDATA)
IS
lcr SYS.LCR$_ROW_RECORD;
rc PLS_INTEGER;
BEGIN
-- Access the LCR
rc := in_any.GETOBJECT(lcr);
-- Insert information about the LCR into the history_row_lcrs table
INSERT INTO strmadmin.history_row_lcrs VALUES
(SYSDATE, lcr.GET_SOURCE_DATABASE_NAME(), lcr.GET_COMMAND_TYPE(),
lcr.GET_OBJECT_OWNER(), lcr.GET_OBJECT_NAME(), lcr.GET_TAG(),
lcr.GET_TRANSACTION_ID(), lcr.GET_SCN(), lcr.GET_COMMIT_SCN,
lcr.GET_VALUES('old'), lcr.GET_VALUES('new', 'n'));
-- Apply row LCR
lcr.EXECUTE(true);
END;/