ITPub博客

首页 > 数据库 > Oracle > 10g Data Guard三种保护模式测试

10g Data Guard三种保护模式测试

原创 Oracle 作者:ora_erin 时间:2014-03-05 20:06:54 0 删除 编辑
在《大话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/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-04-16

  • 博文量
    37
  • 访问量
    633783