10g Data Guard三種保護模式測試

ora_erin發表於2014-03-05
在《大話ORACLE RAC》裡面講到,data guard傳送日誌有三種方式:ARCH、LGWR SYNC、LGWR ASYNC
摘錄如下:
1)使用ARCH程式完成日誌傳送的情況
在primary database不斷產生redo log,這些日誌被LGWR程式寫到聯機重做日誌;
當一組聯機日誌被寫滿後,會發生日誌切換,並且會觸發本地歸檔;
然後歸檔程式通過oracle net把歸檔日誌傳送給standby database的RFS程式;
standby database的RFS程式把接受到的日誌寫入到歸檔日誌;
standby database的MRP程式(redo apply)或者LSP程式(sql apply)在standby database上應用這些日誌,進而同步資料;

使用ARCH程式傳遞最大的問題在於,primary database只有在發生歸檔時才會傳送日誌到standby database,如果primary database異常當機,聯機重做日誌中的redo內容就會丟失,因此使用ARCH程式無法避免資料丟失的問題(預設方式下,primary database使用的就是ARCH程式)。要想避免資料丟失,就必須使用LGWR,而LGWR又有SYNC(同步)和ASYNC(非同步)兩種方式。

2)使用LGWR程式的SYNC方式
primary database產生的redo日誌要同時寫到日誌檔案和網路,也就是說,LGWR程式把日誌寫到本地日誌檔案的同時還要傳送給本地的LNSn程式(network server process),再由LNSn程式把日誌通過網路傳送給遠端目的地,每個遠端目的地對應一個LNSn程式,多個LNS程式能夠並行工作;
LGWR必須等待寫入本地日誌檔案操作和通過LNSn程式的網路傳送都成功,primary database上的事務才能提交,這也是SYNC的含義所在;
standby database的RFS程式把接收到的日誌寫入到standby redo log日誌中;
primary database的日誌切換也會觸發standby database上的日誌切換,即standby database對standby redo log的歸檔,然後觸發standby database的MRP或LSP程式恢復歸檔日誌;

因為primary database的redo是實時傳遞的,於是standby database可以使用兩種恢復方式:
a)實時恢復,只要RFS把日誌寫入standby redo log就會立即進行恢復
b)歸檔時恢復,在完成standby redo log歸檔時才觸發恢復

3)使用LGWR程式的ASYNC方式
使用LGWR SYNC方法的可能問題在於,如果日誌傳送給standby database過程失敗,LGWR程式就會出錯,也就是說,primary database的LGWR程式依賴於網路狀況,有時這種要求可能過於苛刻,這時可以使用LGWR ASYNC方式:
primary database一端產生redo日誌後,LGWR把日誌同時提交給日誌檔案和本地LNS程式,但是LGWR程式只需成功寫入日誌檔案即可,不必等待LNSn程式的網路傳送成功;
LNSn程式非同步地把日誌內容傳送到standby database,多個LNSn程式可以併發傳送;
primary database的online redo log寫滿之後發生log switch,觸發歸檔操作,也觸發standby database對standby redo log的歸檔,然後觸發MRP或LSP程式恢復歸檔日誌;

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

10g中log_archive_dest_n中可以設定arch或lgwr,設定為lgwr的話,又可以分async和sync。ARCH方式在standby database上不需要配置standby redo log,而LGWR SYNC和LGWR ASYNC都需要配置standby redo log。如果arch或lgwr都未指定的話,則預設是arch。如果指定了lgwr,但未指定是sync還是async,則預設是sync。

SQL> show parameter log_archive_dest_2

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
log_archive_dest_2                   string      service=7502 async valid_for=(
                                                 online_logfiles,primary_role)
                                                 db_unique_name=ORCLDG

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
ARCH       ARCH       ACTIVE   SYNCHRONOUS

SQL> alter system set log_archive_dest_2='service=7502 sync valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;

系統已更改。

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
ARCH       ARCH       ACTIVE   SYNCHRONOUS

SQL> alter system set log_archive_dest_2='service=7502 arch async valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;

系統已更改。

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
ARCH       ARCH       ACTIVE   SYNCHRONOUS

SQL> alter system set log_archive_dest_2='service=7502 arch sync valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;

系統已更改。

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
ARCH       ARCH       ACTIVE   SYNCHRONOUS

SQL> alter system set log_archive_dest_2='service=7502 lgwr valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;

系統已更改。

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
LGWR       LGWR       PENDING  PARALLELSYNC

SQL> alter system set log_archive_dest_2='service=7502 lgwr sync valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;

系統已更改。

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
LGWR       LGWR       PENDING  PARALLELSYNC

SQL> alter system set log_archive_dest_2='service=7502 lgwr async valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;

系統已更改。

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
LGWR       LGWR       PENDING  ASYNCHRONOUS

SQL> alter system set log_archive_dest_2='service=7502 valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;

系統已更改。

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
ARCH       ARCH       ACTIVE   SYNCHRONOUS

總結如下:
如果什麼都未指定,則為ARCH程式傳送模式
只指定sync或async,為ARCH程式傳送模式
指定為arch sync或arch async,為ARCH程式傳送模式
指定為lgwr,為LGWR sync傳送模式
指定為lgwr sync,為LGWR sync傳送模式
指定為lgwr ssync,為LGWR async傳送模式

不過11g中,log_archive_dest_n引數的ARCH和LGWR這兩種屬性都已經廢棄了,只用於向後相容,只要指定SYNC或ASYNC就可以了,如果不指定的話,預設是ASYNC。

1、測試maximum performance模式,設定為arch
SQL> alter system set log_archive_dest_2='service=7502 arch valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;

系統已更改。

SQL> select t.ARCHIVER,t.PROCESS,t.SCHEDULE,t.TRANSMIT_MODE from v$archive_dest t where dest_name='LOG_ARCHIVE_DEST_2';

ARCHIVER   PROCESS    SCHEDULE TRANSMIT_MOD
---------- ---------- -------- ------------
ARCH       ARCH       ACTIVE   SYNCHRONOUS

SQL> select database_role,protection_mode,protection_level from v$database;

DATABASE_ROLE    PROTECTION_MODE      PROTECTION_LEVEL
---------------- -------------------- --------------------
PRIMARY          MAXIMUM PERFORMANCE  MAXIMUM PERFORMANCE

在主庫上更改一些資料(備庫現為恢復狀態):
SQL> drop table hr.test;

表已刪除。

SQL> create table hr.test(id int);

表已建立。

SQL> insert into hr.test values(1);

已建立 1 行。

SQL> commit;

提交完成。

SQL> alter system switch logfile;

系統已更改。

主庫:
SQL> select t.group#,t.sequence#,t.archived,t.status from v$log t;
 
    GROUP#  SEQUENCE# ARCHIVED STATUS
---------- ---------- -------- ----------------
         1         26 YES      ACTIVE
         2         27 NO       CURRENT
         3         25 YES      INACTIVE

--剛由26切換為27,並在主庫的v$archived_log中產生兩條26記錄,一條歸檔到本地,一條傳送到備庫上,在備庫的v$archived_log中產生一條26的記錄,過了一會後發現applied標誌變為yes

備庫:
SQL> select t.group#,t.sequence#,t.archived,t.status from v$log t;--雖然備庫上並沒有建立過聯機重做日誌,但是備庫控制檔案中的日誌資訊會跟主庫同步變化,只是狀態顯示不同
    GROUP#  SEQUENCE# ARCHIVED STATUS
---------- ---------- -------- ----------------
         1         26 YES      CLEARING
         3         25 YES      CLEARING
         2         27 YES      CLEARING_CURRENT

SQL> select t.group#,t.dbid,t.sequence#,t.archived,t.status,t.first_change#,t.last_change# from v$standby_log t;--可以看到,arch程式傳送模式,未使用備庫的standby redo log
 
    GROUP# DBID                                      SEQUENCE# ARCHIVED STATUS     FIRST_CHANGE# LAST_CHANGE#
---------- ---------------------------------------- ---------- -------- ---------- ------------- ------------
         4 UNASSIGNED                                        0 NO       UNASSIGNED             0            0
         5 UNASSIGNED                                        0 NO       UNASSIGNED             0            0
         6 UNASSIGNED                                        0 YES      UNASSIGNED             0            0
         7 UNASSIGNED                                        0 YES      UNASSIGNED             0            0

關閉備庫後,在主庫上繼續執行一些變更:
SQL> insert into hr.test values(2);

已建立 1 行。

SQL> commit;--由於是arch模式,即使在備庫不可用的情況下,還是可以提交成功

提交完成。

SQL> alter system switch logfile;

系統已更改。

在主庫的歸檔目錄E:\oracle\product\10.2.0\arch下新生成了1個歸檔日誌,備庫的歸檔目錄E:\oracle\product\10.2.0\arch2是沒有的,將備庫啟動到mount狀態,過了一會兒發現,E:\oracle\product\10.2.0\arch2下已經新增了1個歸檔日誌,這個是由於備庫上fal_server引數在起作用,備庫會自動檢測歸檔間隙,並且從fal_server設定的目的地上取缺失的歸檔日誌過來,但是此時歸檔日誌還是沒有應用的,applied欄位為no,執行命令alter database recover managed standby database disconnect from session進行恢復

SQL> alter database recover managed standby database disconnect from session;

資料庫已更改。

過了一會兒可取消恢復,開啟資料庫驗證是否恢復成功
SQL> alter database recover managed standby database cancel;

資料庫已更改。

SQL> alter database open;

資料庫已更改。

SQL> select * from hr.test;--資料同步成功

        ID
----------
         1
         2

在10g中備庫要麼處於恢復狀態,要麼以只讀方式開啟,不能同時處於2種狀態,但是在11g中可以在資料庫以只讀開啟的狀態下進行恢復。

SQL> alter database recover managed standby database disconnect from session;

資料庫已更改。

SQL> alter database open;--10g中備庫未停止恢復的情況下不能開啟
alter database open
*
第 1 行出現錯誤:
ORA-01154: 資料庫忙。現在不允許開啟, 關閉, 裝載和解除安裝


2、測試maximum protection模式,設定為lgwr sync
根據10g的聯機文件Data Guard Concepts and Administration--Setting the Data Protection Mode of a Data Guard Configuration這一小節,
maximum protection模式要求LGWR,SYNC,AFFIRM,且必須配置standby redo log
maximum availability模式要求LGWR,SYNC,AFFIRM,且必須配置standby redo log
maximum performance模式要求ARCH或LGWR都可以,SYNC或ASYNC都可以,AFFIRM或NOAFFIRM都可以,可以不必但是推薦配置standby redo log

先關閉備庫先
SQL> alter system set log_archive_dest_2='service=7502 lgwr sync affirm valid_for=(online_logfiles,primary_role) db_unique_name=ORCLDG' scope=both;
系統已更改。

這裡注意:必須顯式指定lgwr、sync、affirm,不能採用預設值,否則將資料庫設定為maximum protection後開啟會報錯,並直接關閉例項

SQL> shutdown immediate
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE 例程已經關閉。
SQL> startup mount
ORACLE 例程已經啟動。

Total System Global Area  603979776 bytes
Fixed Size                  1250380 bytes
Variable Size             352324532 bytes
Database Buffers          243269632 bytes
Redo Buffers                7135232 bytes
資料庫裝載完畢。
SQL> alter database set standby database to maximize protection;

資料庫已更改。

SQL> alter database open;
alter database open
*
第 1 行出現錯誤:
ORA-03113: 通訊通道的檔案結束

檢視alert日誌
Wed Mar 05 16:42:53 2014
LGWR: Error 1034 verifying archivelog destination LOG_ARCHIVE_DEST_2
Wed Mar 05 16:42:53 2014
Destination LOG_ARCHIVE_DEST_2 is UNSYNCHRONIZED
LGWR: Continuing...
LGWR: Minimum of 1 applicable standby database required
Wed Mar 05 16:42:53 2014
Errors in file e:\oracle\product\10.2.0\admin\orcl\bdump\orcl_lgwr_7244.trc:
ORA-16072: a minimum of one standby database destination is required

這個錯誤是備庫沒有啟動的緣故,下面啟動備庫到mount狀態,再重新開啟主庫

C:\>sqlplus sys/oracle@7501 as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 3月 5 16:45:51 2014

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

已連線到空閒例程。

SQL> startup
ORACLE 例程已經啟動。

Total System Global Area  603979776 bytes
Fixed Size                  1250380 bytes
Variable Size             352324532 bytes
Database Buffers          243269632 bytes
Redo Buffers                7135232 bytes
資料庫裝載完畢。
資料庫已經開啟。
SQL>

主庫成功開啟,為了演示sync,將備庫關閉,但是在maximum protection模式下,主庫未關閉的情況下,備庫是不能關閉的
SQL> shutdown immediate
ORA-01154: 資料庫忙。現在不允許開啟, 關閉, 裝載和解除安裝

下面強行關閉備庫
SQL> shutdown abort
ORACLE 例程已經關閉。

然後繼續在主庫上做一些變更
SQL> insert into hr.test values(3);

已建立 1 行。

SQL> commit;--提交呈掛起狀態

SQL> select t.dest_id,t.dest_name,t.status,t.target,t.destination,t.net_timeout,t.error from v$archive_dest t;
 
   DEST_ID DEST_NAME                 STATUS    TARGET  DESTINATION                         NET_TIMEOUT ERROR
---------- ------------------------- --------- ------- ----------------------------------- ----------- -----------------------------------
         1 LOG_ARCHIVE_DEST_1        VALID     PRIMARY E:\oracle\product\10.2.0\arch                 0 
         2 LOG_ARCHIVE_DEST_2        ERROR     STANDBY 7502                                        180 ORA-03113: 通訊通道的檔案結束

--從v$archive_dest可以看出,oracle已經檢測到LOG_ARCHIVE_DEST_2發生故障,但是會等待180s的超時

180s後丟擲錯誤:
SQL> commit;
commit
*
第 1 行出現錯誤:
ORA-00603: ORACLE 伺服器會話因致命錯誤而終止

主庫自動關閉了,這就驗證了在最大保護模式下,如果日誌不能寫入備庫的話,主庫會自動關閉

3、測試maximum availability模式,設定為lgwr sync
現備庫還是關閉狀態,開啟主庫
C:\>sqlplus sys/oracle@7501 as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 3月 5 17:00:46 2014

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

已連線到空閒例程。

SQL> startup mount;
ORACLE 例程已經啟動。

Total System Global Area  603979776 bytes
Fixed Size                  1250380 bytes
Variable Size             356518836 bytes
Database Buffers          239075328 bytes
Redo Buffers                7135232 bytes
資料庫裝載完畢。
SQL> show parameter log_archive_dest_2

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
log_archive_dest_2                   string      service=7502 lgwr sync affirm
                                                 valid_for=(online_logfiles,pri
                                                 mary_role) db_unique_name=ORCL
                                                 DG
SQL> alter database set standby database to maximize availability;

資料庫已更改。

SQL> select database_role,protection_mode,protection_level from v$database;

DATABASE_ROLE    PROTECTION_MODE      PROTECTION_LEVEL
---------------- -------------------- --------------------
PRIMARY          MAXIMUM AVAILABILITY UNPROTECTED

SQL> alter database open;--maximum availability模式下,備庫關閉時,可以開啟主庫

資料庫已更改。

SQL> select database_role,protection_mode,protection_level from v$database;

DATABASE_ROLE    PROTECTION_MODE      PROTECTION_LEVEL
---------------- -------------------- --------------------
PRIMARY          MAXIMUM AVAILABILITY RESYNCHRONIZATION

SQL> select * from hr.test;

        ID
----------
         1
         2

SQL> insert into hr.test values(3);

已建立 1 行。

SQL> commit;--即使備庫關閉,也還是可以提交成功

提交完成。

SQL> select database_role,protection_mode,protection_level from v$database;

DATABASE_ROLE    PROTECTION_MODE      PROTECTION_LEVEL
---------------- -------------------- --------------------
PRIMARY          MAXIMUM AVAILABILITY RESYNCHRONIZATION

下面啟動備庫

主庫:
SQL> select t.group#,t.sequence#,t.archived,t.status,t.first_change# from v$log t;
 
    GROUP#  SEQUENCE# ARCHIVED STATUS           FIRST_CHANGE#
---------- ---------- -------- ---------------- -------------
         1         29 YES      INACTIVE         1231512326222
         2         30 YES      ACTIVE           1231512328249
         3         31 NO       CURRENT          1231512328285

備庫:
SQL> select t.group#,t.dbid,t.sequence#,t.archived,t.status,t.first_change#,t.last_change# from v$standby_log t;
 
    GROUP# DBID                                      SEQUENCE# ARCHIVED STATUS     FIRST_CHANGE# LAST_CHANGE#
---------- ---------------------------------------- ---------- -------- ---------- ------------- ------------
         4 1327101518                                       31 YES      ACTIVE     1231512328285 123151232829
         5 UNASSIGNED                                        0 NO       UNASSIGNED             0            0
         6 UNASSIGNED                                        0 YES      UNASSIGNED             0            0
         7 UNASSIGNED                                        0 YES      UNASSIGNED             0            0

--可以看到,在設定為lgwr sync情況下,需要使用備庫中的standby redo log

主庫中再插入一些記錄
SQL> insert into hr.test values(43);

已建立 1 行。

SQL> commit;

提交完成。

主庫:
SQL> select t.group#,t.sequence#,t.archived,t.status,t.first_change# from v$log t;
 
    GROUP#  SEQUENCE# ARCHIVED STATUS           FIRST_CHANGE#
---------- ---------- -------- ---------------- -------------
         1         29 YES      INACTIVE         1231512326222
         2         30 YES      ACTIVE           1231512328249
         3         31 NO       CURRENT          1231512328285

備庫:
SQL> select t.group#,t.dbid,t.sequence#,t.archived,t.status,t.first_change#,t.last_change# from v$standby_log t;
 
    GROUP# DBID                                      SEQUENCE# ARCHIVED STATUS     FIRST_CHANGE#  LAST_CHANGE#
---------- ---------------------------------------- ---------- -------- ---------- -------------  ------------
         4 1327101518                                       31 YES      ACTIVE     1231512328285 12315123282971 
         5 UNASSIGNED                                        0 NO       UNASSIGNED             0            0
         6 UNASSIGNED                                        0 YES      UNASSIGNED             0            0
         7 UNASSIGNED                                        0 YES      UNASSIGNED             0            0

--不斷地查詢v$standby_log,可以看到last_change#一直在變化

在主庫上切換日誌:

主庫:
SQL> select t.group#,t.sequence#,t.archived,t.status,t.first_change# from v$log t;
 
    GROUP#  SEQUENCE# ARCHIVED STATUS           FIRST_CHANGE#
---------- ---------- -------- ---------------- -------------
         1         32 NO       CURRENT          1231512328313
         2         30 YES      INACTIVE         1231512328249
         3         31 YES      ACTIVE           1231512328285

備庫:
SQL> select t.group#,t.dbid,t.sequence#,t.archived,t.status,t.first_change#,t.last_change# from v$standby_log t;
 
    GROUP# DBID                                      SEQUENCE# ARCHIVED STATUS     FIRST_CHANGE# LAST_CHANGE#
---------- ---------------------------------------- ---------- -------- ---------- ------------- ------------
         4 1327101518                                       32 YES      ACTIVE     1231512328313 123151232831
         5 UNASSIGNED                                        0 NO       UNASSIGNED             0            0
         6 UNASSIGNED                                        0 YES      UNASSIGNED             0            0
         7 UNASSIGNED                                        0 YES      UNASSIGNED             0            0

--備庫的sequence#和first_change#已經跟進,但是備庫好像不是迴圈使用的,達到一定的條件後,可以被覆蓋,而不會寫下一組日誌

SQL> alter database recover managed standby database disconnect from session;

資料庫已更改。

SQL> alter database recover managed standby database cancel;

資料庫已更改。

SQL> alter database open;

資料庫已更改。

SQL> select * from hr.test;--資料已經同步

        ID
----------
         1
         2
         3
         4

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

相關文章