在《大话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博客 ” ,链接:https://blog.itpub.net/26524307/viewspace-1101805/
,如需转载,请注明出处,否则将追究法律责任。