企業級災備方案Oracle Stream搭建過程

eymit發表於2012-01-10

1       背景

生產環境和災備放在不同的機房,中間使用20M的專線相連,為了實現兩個機房之間資料庫的災難備份,兩個機房的作業系統不一樣,沒有辦法使用dataguard,於是免費的Stream成為我們的首選,複製時只複製其中兩個使用者,資料庫總大小為1.5T左右,每天生成歸檔量為20-40G左右,執行stream期間除遇到大的事務延遲外,沒有發現有大的效能問題。

 

除災備外還有一個最重要的目的,這種架構可以實現資料庫大版本升級(跨平臺)0風險,只需停機半小時就能完成升級切換, 切換時注意同步sequence

 

2       環境資訊

防止洩露資訊,下面例項名和IP以及要同步的使用者都替換成了無意義的名字

2.1      主庫 ora71

Topic

Description

OS Version

Linux

IP

192.168.0.71

Oracle version

10.2.0.2

SID

ora71

Global name

ora71

 

2.2      災備庫ora72

Topic

Description

OS Version

AIX 6.1

IP

192.168.1.72

Oracle version

11.2.0.2

SID

ora72

Global name

ora72

 

 

3       搭建Stream

 

3.1      清除以前配置

如果源庫已經存在,請先在源庫和目標庫上面清除原來stream配置,一般有兩種方式,更推薦使用方法2

 

方法1

下面操作在stream backup庫上面一定是在impdp之前,因為這個操作會把表的SCN號清掉

connect SYS/password as SYSDBA

 

EXEC DBMS_STREAMS_ADM.REMOVE_STREAMS_CONFIGURATION();

如果.REMOVE_STREAMS_CONFIGURATION報錯也可以先執行刪除使用者操作,再執行清除操作

drop user stream_admin cascade;

 

下面操作可以在impdp之前操作,也可以在之後操作,不涉及到清SCN

 

方法2

也可以使用下面方式

 

1.刪除captrue

 

SQL> exec dbms_capture_adm.drop_capture(CAPTURE_NAME=>'CAPTURE_ORA71',DROP_UNUSED_RULE_SETS=>TRUE);

 

PL/SQL procedure successfully completed

 

 

2.刪除傳播程式

 

exec DBMS_PROPAGATION_ADM.drop_propagation(propagation_name =>'PROP_ORA71_TO_ORA72' ,drop_unused_rule_sets => true);

 

SQL>

 

 

select RULE_NAME,STREAMS_TYPE,STREAMS_NAME from DBA_STREAMS_RULES where rule_owner='STREAM_ADMIN';

 

exec dbms_streams_adm.remove_rule(RULE_NAME=> 'EYMIT116',STREAMS_TYPE=>'CAPTURE',STREAMS_NAME=>'PROP_ORA71_TO_ORA72',DROP_UNUSED_RULE=>TRUE);

 

 

 

--刪除訊息佇列

 select owner,name,QUEUE_TABLE,QUEUE_TYPE from dba_queues where wner='STREAM_ADMIN';

 

OWNER                          NAME                           QUEUE_TABLE                    QUEUE_TYPE

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

STREAM_ADMIN                   ORA71_QUEUE                    ORA71_QUEUE_TABLE              NORMAL_QUEUE

STREAM_ADMIN                   AQ$_ORA71_QUEUE_TABLE_E        ORA71_QUEUE_TABLE              EXCEPTION_QUEUE

 

 

exec dbms_streams_adm.REMOVE_QUEUE(QUEUE_NAME=>'ORA71_QUEUE', CASCADE=>TRUE, DROP_UNUSED_QUEUE_TABLE=>true);

 

3.刪除Apply配置

刪除apply之前需要把所有報錯資訊刪除

exec dbms_apply_adm.delete_all_errors;

 

select APPLY_NAME,status from dba_apply;

 

exec dbms_apply_adm.DROP_APPLY(APPLY_NAME=>'APPLY_ORA71_TO_ORA72',DROP_UNUSED_RULE_SETS=>TRUE);

 

--刪除訊息佇列

SQL>  select owner,name,QUEUE_TABLE,QUEUE_TYPE from dba_queues where wner='STREAM_ADMIN';

 

OWNER                          NAME                           QUEUE_TABLE                    QUEUE_TYPE

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

STREAM_ADMIN                   Q_ORA71_TO_ORA72                    Q_ORA71_TO_ORA72_TABLE              NORMAL_QUEUE

STREAM_ADMIN                   AQ$_Q_ORA71_TO_ORA72_TABLE_E        Q_ORA71_TO_ORA72_TABLE              EXCEPTION_QUEUE

 

SQL>

SQL> exec dbms_streams_adm.REMOVE_QUEUE(QUEUE_NAME=>'Q_ORA71_TO_ORA72', CASCADE=>TRUE, DROP_UNUSED_QUEUE_TABLE=>true);

 

PL/SQL procedure successfully completed

 

 

3.2      修改oracle 引數

 

COMPATIBLE

預設值: 10.0.0

是否必須修改:

Oracle 10g R2必須設定為10.2.0或更高.

GLOBAL_NAMES

預設: false

是否必須修改:

兩邊都必須設定為true

JOB_QUEUE_PROCESSES

預設: 10

是否必須修改:

最低為2

LOG_ARCHIVE_CONFIG

預設: 'SEND, RECEIVE, NODG_CONFIG'

是否必須修改:

如果是下游stream必須要設定

LOG_ARCHIVE_CONFIG

 

 

LOG_ARCHIVE_DEST_n

預設無

是否必須修改:

需要指定歸檔日誌路徑(開啟歸檔)

LOG_ARCHIVE_DEST_STATE_n

預設: enable

 

OPEN_LINKS

預設: 4

是否必須修改:

Stream環境確保最小為4

PARALLEL_MAX_SERVERS

預設:自動分配

是否必須修改:

設定一個合適的值

PROCESSES

預設:40

是否必須修改:

設定合適的值,我們設定為1000

SGA_MAX_SIZE

預設:SGA

 

SGA_TARGET

預設:0

是否必須修改:

設定為動態分配

SHARED_POOL_SIZE

預設:0

是否必須修改:

大於84M,如果SGA_TARGETSTREAMS_

POOL_SIZE沒有設定,stream將從shared pool中分配10%

STREAMS_POOL_SIZE

預設:0

是否必須修改:

如果設定為0 stream將不會跑,每個captrue程式最少10 MB ,每個佇列最少10Mstream庫上面每個apply程式最少1M

 

TIMED_STATISTICS

預設: TYPICAL.

是否必須修改:

必須為TYPICAL或者 ALL

UNDO_RETENTION

預設: 900

是否必須修改:

Stream要求最少3600

 

 

Login as SYSDBA

Connect "/ as sysdba"

 

3.2.1     Global_Names

SQL> alter system set global_names=true scope=both sid='*';

System altered.

如果某個資料庫的GLOBAL_NAMES引數設定成了TRUE,那麼要求該資料庫上DB Link名字與連線的對方的資料庫的Golbal Name相同。

 

alter system set streams_pool_size=100M scope=both sid='*';

alter system set undo_retention=9000  scope=both sid='*';

alter system set nls_date_format='YYYY-MM-DD HH24:MI:SS' scope=spfile sid='*';

alter system set aq_tm_processes=2 scope=both sid='*';

alter system set parallel_max_servers=20 scope=both sid='*';

 

 

 

檢視哪些物件不支援

select * from DBA_STREAMS_UNSUPPORTED where wner='EYMIT'

在傳輸過程中確保這個不支援的物件是隻讀的

3.3      在主庫上面建立管理stream的使用者

3.3.1     Create tablespace for stream

create tablespace stream_tbs

  datafile '+DATAVG' size 100m autoextend  on next 500m maxsize 20g segment space management auto;

 

3.3.2     Create stream_admin user

create user stream_admin identified by stream_xxxxx default tablespace stream_tbs temporary tablespace temp;

 

3.3.3     Grant privilege to stream_admin

grant connect,resource,dba,aq_administrator_role to stream_admin;

 

begin

dbms_streams_auth.grant_admin_privilege(

grantee => 'stream_admin',

grant_privileges => true);

end;

/

3.3.4     Change the default tablespace of Logminer

#logminer的資料字典從system表空間轉移到新建的表空間,防止撐滿system表空間

SQL> execute dbms_logmnr_d.set_tablespace('stream_tbs');

 

 

3.4      在災備庫上面建立管理stream的使用者

#sysdba身份登入

connect / as sysdba

 

 

3.4.1     Create tablespace for stream

 

create tablespace stream_tbs

  datafile '/oradata/ora72/stream_tbs01.dbf' size 100m autoextend  on next 500m maxsize 20g segment space management auto;

 

3.4.2     Create stream_admin user

create user stream_admin  identified by stream_xxxxx

default tablespace stream_tbs temporary tablespace temp;

 

3.4.3     Grant privilege to stream_admin

grant connect,resource,dba,aq_administrator_role to stream_admin ;

 

begin

dbms_streams_auth.grant_admin_privilege(

grantee => 'stream_admin ',

grant_privileges => true);

end;

/

 

 

3.4.4     Change the default tablespace of Logminer

execute dbms_logmnr_d.set_tablespace('stream_tbs');

 

 

 

3.5      配置tnsnames.ora

3.5.1     Config tnsnames.ora of Master DB

主庫(tnsnames.ora)中新增Backup Database配置。

ora72 =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.72)(PORT = 1522))

    )

    (CONNECT_DATA =

      (SID = ora72)

      (SERVER = DEDICATED)

    )

  )

 

3.5.2     Config tnsnames.ora of Backup DB

Backup Databasetnsnames.ora)中新增主庫配置。

ora71 =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.71)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SID = ora71)

      (SERVER = DEDICATED)

    )

  )

 

3.6      在主庫上面啟用 supplemental log

使所有操作都記錄在redo log中,防止部分手動設定nolog的操作不能記錄到redo log中,從而導致資料不同步

 

ALTER DATABASE FORCE LOGGING;

 

啟用追加日誌(Supplemental Log),可以基於Database級別或Table級別

 

sysdba登入master資料庫

#檢查是否啟用了追加日誌:

SELECT SUPPLEMENTAL_LOG_DATA_MIN,SUPPLEMENTAL_LOG_DATA_PK, SUPPLEMENTAL_LOG_DATA_UI,SUPPLEMENTAL_LOG_DATA_ALL FROM V$DATABASE;

 

 

#啟用Database Supplemental Log

 

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA

   (PRIMARY KEY, UNIQUE, FOREIGN KEY,ALL) COLUMNS;

 

 

如果需要刪除SUPPLEMENTAL

ALTER DATABASE DROP SUPPLEMENTAL LOG DATA

(PRIMARY KEY, UNIQUE, FOREIGN KEY,ALL) COLUMNS;

 

3.7      建立 Database Link

3.7.1     Create 主庫 Link

#stream_admin 身份,登入主庫。

connect stream_admin /stream_xxxxx@ora71

create database link ora72 connect to stream_admin  identified by stream_xxxxx  using 'ora72';

 

3.7.2     Create 災備庫Link

#stream_admin 身份,登入Backup Database

connect stream_admin/stream_xxxxx

create database link ora71 connect to stream_admin  identified by stream_xxxxx  using 'ora71';

 

3.7.3     Test Database Link

測試兩個DBLINK的可用性

 

 

3.8    同步使用者的匯入匯出

 

 

3.8.1     create Tablespace and User on Backup DB

# Tablespace

CREATE SMALLFILE TABLESPACE "EYMIT"

  DATAFILE '/oradata/ora72/EYMIT_01.dbf' SIZE 2G AUTOEXTEND ON NEXT 128M MAXSIZE UNLIMITED

  LOGGING

  EXTENT MANAGEMENT LOCAL

  SEGMENT SPACE MANAGEMENT AUTO;

 

# Users

 

create user EYMIT

  identified by EYMITpwd

  default tablespace EYMIT_TBS

  temporary tablespace TEMP

  profile DEFAULT;

-- Grant/Revoke object privileges

-- Grant/Revoke role privileges

grant connect to EYMIT;

grant resource to EYMIT;

-- Grant/Revoke system privileges

grant create any synonym to EYMIT;

grant create any table to EYMIT;

grant unlimited tablespace to EYMIT;

 

 

-- Create the user

create user EYMIT2

  identified by EYMIT2pwd

  default tablespace EYMIT2_TBS

  temporary tablespace TEMP

  profile DEFAULT;

-- Grant/Revoke role privileges

grant connect to EYMIT2;

grant resource to EYMIT2;

-- Grant/Revoke system privileges

grant create any synonym to EYMIT2;

grant create session to EYMIT2;

grant create synonym to EYMIT2;

grant debug connect session to EYMIT2;

grant select any dictionary to EYMIT2;

grant unlimited tablespace to EYMIT2;

 

 

 

 

3.8.2     Export shema

在匯入前確保STREAM目標資料庫中沒有JOB在更改目標庫中的資料

使用expdp的方式

 

在源使用者中初始化SCN

sqlplus stream_admin/stream_xxxxx

 

BEGIN
DBMS_CAPTURE_ADM.PREPARE_SCHEMA_INSTANTIATION(
schema_name => 'EYMIT');
END;
/

 

BEGIN
DBMS_CAPTURE_ADM.PREPARE_SCHEMA_INSTANTIATION(
schema_name => 'EYMIT2');
END;
/

 

 

 

匯出前一定要檢查undo_retention的時間比匯出時間長.

 

SQL> show parameter  undo_retention

 

NAME                                 TYPE                   VALUE

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

undo_retention                       integer                56000

SQL>

 

 

SCN號資訊寫到redo log,不執行下面語句取不到符合條件的SCN.

exec DBMS_CAPTURE_ADM.BUILD();

 

取得當前SCN,確保這個arch logfile是有效且存在在磁碟中的.

 

Select FIRST_CHANGE#,name from v$archived_log where dictionary_begin='YES';

 

從源庫匯出,注意需要加入flashback_scn,加入scn後匯出的表不會都是這個SCN號,但是都會比這個SCN號大,一般相關聯的表會是同一個SCN

 

                                                                                              

expdp userid/password dumpfile= directory=  flashback_scn=

如:

 

expdp system/xxxxxx directory=expdp_dir dumpfile=expdp_ora71_20120824_%U.dmp   schemas=EYMIT2,EYMIT  exclude=TABLE:\"IN \(\'T_A

TTACHMENT\'\)\",STATISTICS   flashback_scn=1110227790  PARALLEL=5

 

匯入到目標庫

impdp userid/password dumpfile= directory=

如:

impdp system/xxxx  directory=expdp_dir dumpfile= expdp_ora71_20120824_%U.dmp    logfile=impdp_ora71_20110916.log  EXCLUDE=grant 

PARALLEL=3    REMAP_TABLESPACE=EYMIT_TBS:EYMIT_tbs,CIRCBJ_ACC_TBS:EYMIT2_tbs

 

 

3.9      建立stream訊息佇列

 

3.8.1         在主庫上面建立佇列

 

#stream_admin 身份,登入主庫。

connect stream_admin /stream_admin@ora71

begin

dbms_streams_adm.set_up_queue(

queue_table => 'ora71_queue_table',

queue_name => 'ora71_queue');

end;

/

 

#同時,也建立了queue table。一個queue table可以有多個queue

 

 

3.8.2     在災備庫上面建立佇列

#stream_admin 身份,登入Backup Database

connect stream_admin /stream_admin@ora72

begin

dbms_streams_adm.set_up_queue(

queue_table => 'q_table_ora71_to_ora72',

queue_name  => 'q_ora71_to_ora72');

end;

/

3.10   在主庫上面建立Capture捕獲程式

 

#stream_admin 身份,登入主庫。

connect stream_admin /stream_admin@ora71

                

 

execute DBMS_CAPTURE_ADM.CREATE_CAPTURE(queue_name => 'ora71_queue', capture_name => 'capture_ora71', use_database_link=>TRUE,start_scn=>1741155485, first_scn=>1741155485);

 

注意這裡的start_scn and first_scn是從上面檢視v$archived_log中取得.

 

注意如果同步兩個使用者,需要更改變shema_name後再執行一次

 

begin

dbms_streams_adm.add_schema_rules(

schema_name        => 'EYMIT',

streams_type       => 'capture',

streams_name       => 'capture_ora71',

queue_name         => 'ora71_queue',

include_dml        => true,

include_ddl        => true,

include_tagged_lcr => false,

source_database    => null,

inclusion_rule     => true);

end;

/

 

 

begin

dbms_streams_adm.add_schema_rules(

schema_name        => 'EYMIT2',

streams_type       => 'capture',

streams_name       => 'capture_ora71',

queue_name         => 'ora71_queue',

include_dml        => true,

include_ddl        => true,

include_tagged_lcr => false,

source_database    => null,

inclusion_rule     => true);

end;

/

3.11   在主庫上面建立propagation傳播程式

#stream_admin 身份,登入主庫。

注意如果同步兩個使用者,需要更改變shema_name後再執行一次

 

connect stream_admin/stream_admin

begin

dbms_streams_adm.add_schema_propagation_rules(

schema_name            => 'EYMIT',

streams_name           => 'prop_ora71_to_ora72',

source_queue_name      => 'stream_admin.ora71_queue',

destination_queue_name => 'stream_admin.q_ora71_to_ora72@ora72',

include_dml            => true,

include_ddl            => true,

include_tagged_lcr     => false,

source_database        => 'ora71',

queue_to_queue =>true,

inclusion_rule         => true);

end;

/

 

begin

dbms_streams_adm.add_schema_propagation_rules(

schema_name            => 'EYMIT2',

streams_name           => 'prop_ora71_to_ora72',

source_queue_name      => 'stream_admin.ora71_queue',

destination_queue_name => 'stream_admin.q_ora71_to_ora72@ora72',

include_dml            => true,

include_ddl            => true,

include_tagged_lcr     => false,

queue_to_queue =>true,

source_database        => 'ora71',

inclusion_rule         => true);

end;

/

 

#修改propagation休眠時間為0,實時傳播LCR

begin

dbms_aqadm.alter_propagation_schedule(

queue_name             => 'ORA71_QUEUE',

destination            => '"STREAM_ADMIN"."Q_ORA71_TO_ORA72"@ORA72',

latency                => 0);

end;

/

Primary庫上面設定captureSGA100M,避免出現效能問題

 

-- set the SGA size of capture.

EXEC dbms_capture_adm.set_parameter('CAPTURE_ORA71','_SGA_SIZE','100');

 

 

 

3.12   在災備庫上面建立Apply應用程式

#stream_admin 身份,登入Backup Database

connect stream_admin /stream_admin

如果同步2個使用者需要建兩個rules

begin

dbms_streams_adm.add_schema_rules(

schema_name        => 'EYMIT',

streams_type       => 'apply',

streams_name       => 'apply_ora71_to_ora72',

queue_name         => 'stream_admin.q_ora71_to_ora72',

include_dml        => true,

include_ddl        => true,

include_tagged_lcr => false,

source_database    => 'ora71',

inclusion_rule     => true);

end;

/

 

begin

dbms_streams_adm.add_schema_rules(

schema_name        => 'EYMIT2',

streams_type       => 'apply',

streams_name       => 'apply_ora71_to_ora72',

queue_name         => 'stream_admin.q_ora71_to_ora72',

include_dml        => true,

include_ddl        => true,

include_tagged_lcr => false,

source_database    => 'ora71',

inclusion_rule     => true);

end;

/

 

如果要應用的使用者和源使用者不一樣,需要進行改使用者操作,注意只能改DML,不能改DDL操作,也就是說當執行DDL操作時會報錯

exec  dbms_streams_adm.rename_schema(rule_name        => agent_rule_name_dml,

                                 from_schema_name => 'EYMIT',

                                 to_schema_name   => 'PUBEYMIT',

                                 operation        => 'ADD');

 

http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_streams_adm.htm#sthref11008

 

 

 

 

Backup DB庫中設定apply的程式為111g預設為4,貌似是Bug(ID 345119.1),不修改沒有主鍵的表同步會報錯

-- 設定apply程式的並行數量

BEGIN

 DBMS_APPLY_ADM.SET_PARAMETER(

     apply_name  => 'APPLY_ORA71_TO_ORA72',

     parameter   => 'PARALLELISM',

     value       => 1 );

END;

/

 

 

查詢初始化的SCN是否存在或正確

select * from DBA_APPLY_INSTANTIATED_OBJECTS;

 

已執行到這一步

3.13   在主庫上面過濾不需要同步的表

 

 

 

#stream_admin 身份,登入主庫。

建立排除RULE , T_ATTACHMENT為附件表,裡面有不支援的列,MV_FC_VEHICLE為物化檢視,STREAM不支援

connect stream_admin/stream_admin

 

 

---1

BEGIN

DBMS_STREAMS_ADM.ADD_TABLE_RULES

(

table_name => 'EYMIT2.EXCLUE_TABLE1',

streams_type => 'capture',

streams_name => 'capture_ORA71',

queue_name => 'ORA71_queue',

include_dml => true,

include_ddl => true,

source_database => null,

inclusion_rule => false

);

END;

/

 

 

 

backup庫禁用不同步表的外來鍵約束

SELECT a.*, 'alter table '||A.owner||'.'||a.table_name||' disable constraints '||a.constraint_name||';'

  FROM DBA_CONSTRAINTS a

 WHERE A.owner IN ('EYMIT2','EYMIT')

 AND  R_CONSTRAINT_NAME IN

       (SELECT CONSTRAINT_NAME

          FROM DBA_CONSTRAINTS

         WHERE TABLE_NAME = 'T_ATTACHMENT'

           AND CONSTRAINT_TYPE IN ('P','U'));

 

 

 

3.14   啟動STREAM

#stream_admin 身份,登入Backup Database

connect stream_admin /stream_admin

 

#啟動Apply程式

begin

dbms_apply_adm.start_apply(

apply_name => 'apply_ora71_to_ora72');

end;

/

 

#stream_admin 身份,登入主庫。

connect stream_admin /stream_admin

 

#啟動Capture程式

begin

dbms_capture_adm.start_capture(

capture_name =>'capture_ora71');

end;

/

 

 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21605631/viewspace-759699/,如需轉載,請註明出處,否則將追究法律責任。

相關文章