很多人看电影或者电视剧时往往都以为,影响剧情发展的关键是主角的命运,那么,我不得不又说,你只看到了问题的表面,真正影响剧情发展的...............是导演。对于data guard 的数据应用而言,幕后的导演是LOG_ARCHIVE_DEST_n。本章节我们要学习的内容会很多,这一次,希望你能理清要学习的重点。
在primary 数据库,DataGuard 可以使用归档进程(ARCn)或者日志写进程(LGWR)收集redo 数据并传输到standby,不过不管你选择归档进程也好,日志写进程也好,都由一个核心参数来控制,它就是:LOG_ARCHIVE_DEST_n,所以,我们先来:
提示:
对于每一个LOG_ARCHIVE_DEST_n 参数,还有一个对应的LOG_ARCHIVE_DEST_STATE_n 参数。LOG_ARCHIVE_DEST_STATE_n 参数用来指定对应的LOG_ARCHIVE_DEST_n 参数是否生效,拥有4 个属性值:
● ENABLE:默认值,表示允许传输服务。
● DEFER:该属性指定对应的log_archive_dest_n 参数有效,但暂不使用。
● ALTERNATE:禁止传输,但是如果其它相关的目的地的连接通通失败,则它将变成enable。
● RESET:功能与DEFER 属性类似,不过如果传输目的地之前有过错误,它会清除其所有错误信息。
LOG_ARCHIVE_DEST_1='LOCATION=/arch1/chicago/'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
LOG_ARCHIVE_DEST_2='SERVICE=jsspdg'
LOG_ARCHIVE_DEST_STATE_2=ENABLE
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=jsspdgVALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)';
默认情况下,redo 传输服务使用ARCn 进程归档redo 日志。不过ARCn 归档进程只支持最高性能的保护模式。如果standby 数据库处于其它类型的保护模式,那你必须使用LGWR 传输redo 数据(为什么会这样呢,三思再来白话几句,我们知道对于最大保护和最高可用性两种模式而言,其实强调的都是一点,redo数据必须实时应用于standby 数据库,我们再看来归档,归档是做什么呢?是备份已完成切换的redolog,完成切换的redolog 代表着什么呢?说明该redo 中所有数据均已提交至数据文件,那好我们再回过头来看,数据已完成提交的redo 并且完成了切换还被复制了一份做为归档,这个时候才准备开始传输到standby 数据库,这与最大保护和最高可用所要求的实时应用差的简直不是一点半点,现在,你是不是明白了为什么ARCn 归档进程只能支持最高性能的保护模式)。
LOG_ARCHIVE_DEST_n 及LOG_ARCHIVE_MAX_PROCESSES。
ALTER SYSTEM SET LOG_ARCHIVE_MAX_PROCESSES = n;
注:n>0 and n<=30● 在standby 数据库,RFS 进程轮流将redo 数据写入standby redo log,再由standby 数据库中的ARCn 进程将其写入归档,然后通过REDO 应用或SQL 应用将数据应用到standby 数据库。
另外,因为本地的归档进程与远程归档进程间并无联系,注意如果本地存在删除完成备份的归档的策略,需要在删除之前首先确认这些归档已经被传输到standby 数据库。
使用LGWR 进程与使用ARCn 进程有明显不同,LGWR 无须等待日志切换及完成归档。
Standby 数据库的LGWR 进程会先选择一个standby redo log 文件映射primary 数据库当前redolog 的sequence(以及文件大小),一旦primary 数据库有redo 数据产生,视LOG_ARCHIVE_DEST_n 初始化参数中sync 或async 属性设置,以同步或非同步方式传输到standby 数据库。
要继续下面的内容,我们必须先了解与LGWR 归档进程密切相关的几个LOG_ARCHIVE_DEST_n 参数的属性,如果选择LGWR 归档redo 数据,那么在LOG_ARCHIVE_DEST_n中必须指定SERVICE 和LGWR属性以允许日志传输服务使用LGWR 进程来传送redo 数据到远程归档目的地。我们还需要指定SYNC(同步)还是ASYNC(异步)的传输方式,如果指定SYNC 属性(如果不明确指定的话,默认是SYNC),则primary数据库任何会产生redo 操作都会同步触发网络I/O,并且等到网络I/O 全部完成才会继续下面的提交,而如果指定了ASYNC 属性,则会primary 数据库的操作会先记录online redologs,然后再传输到standby。下面详细看看其流程:
LOG_ARCHIVE_DEST_1='LOCATION=E:\ora10g\oradata\jssweb\'
LOG_ARCHIVE_DEST_2='SERVICE=jsspdg LGWR SYNC NET_TIMEOUT=30'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
LOG_ARCHIVE_DEST_STATE_2=ENABLE
如果设置LOG_ARCHIVE_DEST_n 初始化参数SYNC 属性,建议同时设置NET_TIMEOUT 属性,该属性控制网络连接的超时时间,如果超时仍无响应,则会返回错误信息。
如图:
展示了primary 数据库LGWR 写online redologs 的同时,同步传输redo 数据到standby 数据库的过程。
● standby 数据库的RFS(Remote File Server)将接收到的redo 数据写入standby redolog。特别注意, 在此期间, primary 数据库的事务会一直保持, 直到所有所有含LGWR SYNC 属性的LOG_ARCHIVE_DEST_n 指定路径均已完成接收。
LOG_ARCHIVE_DEST_1='LOCATION=E:\ora10g\oradata\jssweb\ '
LOG_ARCHIVE_DEST_2='SERVICE=jsspdg LGWR ASYNC'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
LOG_ARCHIVE_DEST_STATE_2=ENABLE
ASYNC 方式归档就不需要再指定NET_TIMEOUT 了,因为LGWR 与LNSn 之间已无关联,所以指定不指定NET_TIMEOUT 就都没任何影响了,因此对于异步传输而言,即使网络出现故障造成primary 与standby 之间通信中断,也并不会影响到primary 数据库的提交。
展示了LNSn 进程异步传输redo 数据到standby 数据库RFS 进程的过程。
database_role 可设置为:PRIMARY_ROLE,STANDBY_ROLE,ALL_ROLES
注意valid_for 参数是有默认值的,如果不设置的话,其默认值等同于:valid_for=(ALL_LOGFILES,ALL_ROLES)
● SEND 允许数据库发送数据到远端
● RECEIVE 则允许standby 接收来自其它数据库的数据
● NOSEND,NORECEIVE 自然就是禁止喽。
LOG_ARCHIVE_CONFIG='NORECEIVE,DG_CONFIG=(jssweb,jsspdg)'
对于归档失败的处理,LOG_ARCHIVE_DEST_n 参数有几个属性可以用来控制一旦向归档过程中出现故障时应该采取什么措施,它们是:
使用REOPEN=seconds(默认=300)属性,在指定时间重复尝试向归档目的地进行归档操作,如果该参数值设置为0,则一旦失败就不会再尝试重新连接并发送,直到下次redo 数据再被归档时会重新尝试,不过并不会归档到已经失败的归档目的地,而是向替补的归档目的地发送。
alternate 属性定义一个替补的归档目的地,所谓替补就是一旦主归档目的地因各种原因无法使用,则临时向alternate 属性中指定的路径写。
需要注意一点,reopen 的属性会比alternate属性优先级要高,如果你指定reopen 属性的值>0,则lgwr/arch会首先尝试向主归档目的地写入,直到达到最大重试次数,如果仍然写入失败,才会向alternate 属性指定的路径写。
LOG_ARCHIVE_DEST_1='LOCATION=E:\ora10g\oradata\jsspdg\ REOPEN=60 MAX_FAILURE=3'
如果primary 数据库中的归档日志没能成功发送至standby 数据库,就会出现归档中断。当然通常情况下你不需要担心这一点,因为dg 会自动检测并尝试复制丢失的归档以解决中断问题,通过什么解决呢? FAL(Fetch Archive Log)。
● 当创建物理或逻辑的standby 数据库,FAL 机制会自动获取primary 数据库热备时产生的归档文件。
● 当接收的归档文件出现下列的问题时,FAL 机会会自动获取归档文件解决:
※ 当接收到的归档在应用之后被删除时;
※ 当接收到的归档所在磁盘损坏时;
● 当存在多个物理standby 时,FAL 机制会自动尝试从其它standby 服务器获取丢失的归档文件。
SQL> select *from v$archive_gap;
SQL> SELECT NAME FROM V$ARCHIVED_LOG WHERE THREAD#=1 AND DEST_ID=1 ANDSEQUENCE# BETWEEN 7 AND 10;
然后通过alter database register logfile 命令将这些文件重新注册一下,例如:
SQL> ALTER DATABASE REGISTER LOGFILE 'e:\ora10g\jsspdg\xxxx.arc';
SQL> select thread#,sequence#,file_name from dba_logstdby_log l
2 where next_change# not in (
3 select first_change# from dba_logstdby_log where l.thread# = thread#)
4 order by thread#,sequence#;
-The End-