WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606
全部博文(599)
分类: Oracle
2010-01-21 10:13:14
关于redo传输服务(Redo Transport Services),它不仅控制着传输redo数据到其它数据库,同时还管理着解决由于网络中断造成的归档文件未接收的过程。
一、如何发送数据
在primary数据库,DataGuard可以使用归档进程(ARCn)或者日志写进程(LGWR)收集redo数据并传输到standby,不过不管你选择归档进程也好,日志写进程也好,都由一个核心参数来控制,它就是:LOG_ARCHIVE_DEST_n,所以,我们先来:
1、认识LOG_ARCHIVE_DEST_n参数
LOG_ARCHIVE_DEST_n(n从1到10)定义redo文件路径。该参数定义必须通过location或service指明归档文件路径。location表示本地路径,service通常是net service name,即接收redo数据的standby数据库。
提示:
对于每一个LOG_ARCHIVE_DEST_n参数,还有一个对应的LOG_ARCHIVE_DEST_STATE_n参数。LOG_ARCHIVE_DEST_STATE_n参数用来指定对应的LOG_ARCHIVE_DEST_n参数是否生效,拥有4个属性值:
l ENABLE:默认值,表示允许传输服务。
l DEFER:该属性指定对应的log_archive_dest_n参数有效,但暂不使用。
l ALTERNATE:禁止传输,但是如果其它相关的目的地的连接通通失败,则它将变成enable。
l RESET:功能与DEFER属性类似,不过如果传输目的地之前有过错误,它会清除其所有错误信息。
例如:指定本地归档路径
LOG_ARCHIVE_DEST_1='LOCATION=/arch1/chicago/'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
又比如,指定redo传输服务
LOG_ARCHIVE_DEST_2='SERVICE=jsspdg'
LOG_ARCHIVE_DEST_STATE_2=ENABLE
当然,LOG_ARCHIVE_DEST_n参数的属性远不止这些。
这些参数都可以通过alter system set语句直接联机修改,修改会在primary下次日志切换时生效,当然你直接shutdown再重启数据库的话也会即时生效:)比如:
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=jsspdg VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)';
除show parameter log_archive_dest外,还可以通过查询V$ARCHIVE_DEST视图的方式查看参数配置,并且V$ARCHIVE_DEST视图还可以看到更详细的同步信息。
2、使用ARCn归档redo数据
默认情况下,redo传输服务使用ARCn进程归档redo日志。不过ARCn归档进程只支持最高性能的保护模式。如果standby数据库处于其它类型的保护模式,那你必须使用LGWR传输redo数据(为什么会这样呢,三思再来白话几句,我们知道对于最大保护和最高可用性两种模式而言,其实强调的都是一点,redo数据必须实时应用于standby数据库,我们再看来归档,归档是做什么呢?是备份已完成切换的redolog,完成切换的redolog代表着什么呢?说明该redo中所有数据均已提交至数据文件,那好我们再回过头来看,数据已完成提交的redo并且完成了切换还被复制了一份做为归档,这个时候才准备开始传输到standby数据库,这与最大保护和最高可用所要求的实时应用差的简直不是一点半点,现在,你是不是明白了为什么ARCn归档进程只能支持最高性能的保护模式)。
1).初始化参数控制ARCn归档行为
影响ARCn进程的初始化参数有:
LOG_ARCHIVE_DEST_n及LOG_ARCHIVE_MAX_PROCESSES。
关于LOG_ARCHIVE_DEST_n参数的配置前面介绍了一些,我们知道该参数的部分属性与ARCn进程相关,而LOG_ARCHIVE_MAX_PROCESSES初始化参数则可看做是专为ARCn进程量身打造,该参数用来指定最大可被调用的ARCn进程的数量,注意我们指定的是最大值,也就是说数据库在运行过程中是会根据归档的任务繁重程度自动调节归档进程数量的。当然如果说你觉着你的系统归档任务比较繁重,可以通过设置较多的归档进程数量提高归档并发度,但是这个数字也不是越高越好,过高的归档进程数量有可能反而影响系统性能(所谓物极必反就是这个意思,所以这中间是需要你来把握平衡的,当然这方面更多涉及到调优了,非本章所要讲解之重点,就不多说了)。调整该参数可以通过下列语句:
ALTER SYSTEM SET LOG_ARCHIVE_MAX_PROCESSES = n;
注:n>0 and n<=30
2).ARCn的归档过程
primary数据库日志发生切换时就会启动归档:
l 在primary数据库(假设有2个归档进程),一旦ARC0进程完成redolog的归档,ARC1进程即开始传输该归档到standby数据库的指定路径。
l 在standby数据库,RFS进程轮流将redo数据写入standby redo log,再由standby数据库中的ARCn进程将其写入归档,然后通过REDO应用或SQL应用将数据应用到standby数据库。
如图:[024_1.gif]
另外,因为本地的归档进程与远程归档进程间并无联系,注意如果本地存在删除完成备份的归档的策略,需要在删除之前首先确认这些归档已经被传输到standby数据库。
3、使用LGWR归档redo数据
使用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。下面详细看看其流程:
1).LGWR同步归档的流程
例如初始化参数中有如下设置:
LOG_ARCHIVE_DEST_1='LOCATION=E:ora10goradatajssweb '
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属性,该属性控制网络连接的超时时间,如果超时仍无响应,则会返回错误信息。
图:[024_2.gif]
展示了primary数据库LGWR写online redologs的同时,同步传输redo数据到standby数据库的过程。
我们仍然分两部分来解读:
l 在primary数据库,LGWR提交redo数据到LNSn(LGWR Network Server process)进程(n>0),LNSn启动网络传输。
l standby数据库的RFS(Remote File Server)将接收到的redo数据写入standby redolog。特别注意,在此期间,primary数据库的事务会一直保持,直到所有所有含LGWR SYNC属性的LOG_ARCHIVE_DEST_n指定路径均已完成接收。
一旦primary数据库执行日志切换,就会级联触发standby的ARCn将standby redo写入归档,然后通过redo应用(MRP进程)或sql应用(LSP进程)读取归档文件将数据应用至standby数据库。(如果启用了实时应用的话,MRP/LSP会直接读取standby redolog并应用到standby数据库,无须再等待归档)。
2).LGWR不同步归档的流程
例如初始化参数中有如下设置:
LOG_ARCHIVE_DEST_1='LOCATION=E:ora10goradatajssweb '
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数据库的提交。
图:[024_3.gif]
展示了LNSn进程异步传输redo数据到standby数据库RFS进程的过程。
大致步骤与同步传输相同,差别只在LNSn进程这里,LGWR写数据到online redolog,LNSn进程访问online redolog并传输数据到远程standby的RFS而不再与本地LGWR之间有联系。standby数据库方面的处理逻辑仍然不变。
二、什么时候发送
这小节包含两个内容,发送什么,以及发送给谁:
1、 通过VALID_FOR属性指定传输及接收对象
valid_for,字面理解就是基于xx有效,再配合其redo_log_type,database_role属性,我们基本上可以将其理解为:为指定角色设置日志文件的归档路径,主要目的是为了辅助一旦发生角色切换操作后数据库的正常运转。
redo_log_type可设置为:ONLINE_LOGFILE,STANDBY_LOGFILE,ALL_LOGFILES
database_role可设置为:PRIMARY_ROLE,STANDBY_ROLE,ALL_ROLES
注意valid_for参数是有默认值的,如果不设置的话,其默认值等同于:
valid_for=(ALL_LOGFILES,ALL_ROLES)
推荐主动设置该参数而不要使用默认值,某些情况下默认的参数值不一定合适,比如逻辑standby就不像物理standby,逻辑standby处于open模式,不仅有redo数据而且还包含多种日志文件(online redologs,archived redologs以及standby redologs)。多数情况下,逻辑standby生成的online redologs与standby redologs生成在相同的目录内。因此,推荐你对每个*dest设置合适的valid_for属性。
2、 通过DB_UNIQUE_NAME属性指定数据库
DB_UNIQUE_NAME属性主要是为某个数据库指定唯一的数据库名称,这就使得动态添加standby到包含RAC结构的primary数据库的dg配置成为可能,并且对于log_archive_dest_n中的service属性,其属性值对应的也必然是db_unique_name,也正因有了db_unique_name,redo数据在传输过程中才能确认传输到你希望被传输到的数据库上。当然要保障传输redo数据到指定服务器,除了db_unique_name,log_archive_dest_n之外,还有一个初始化参数:log_archive_config。
关于log_archive_config呢,我们前面有过一些接触,在第二部分第1节中也有一些简单的介绍,log_archive_config初始化参数还包括几个属性,可以用过控制数据库的传输和接收,SEND,NOSEND,RECEIVE,NORECEIVE:
l SEND允许数据库发送数据到远端
l RECEIVE则允许standby接收来自其它数据库的数据
l NOSEND,NORECEIVE自然就是禁止喽。
例如,设置primary数据库不接收任何归档数据,可以做如下的设置:
LOG_ARCHIVE_CONFIG='NORECEIVE,DG_CONFIG=(jssweb,jsspdg)'
当然,你同样也需要注意,一旦做了如上的设置,那么假设该服务器发生了角色切换,那它仍然也没有接收redo数据的能力哟。
出错了咋整
对于归档失败的处理,LOG_ARCHIVE_DEST_n参数有几个属性可以用来控制一旦向归档过程中出现故障时应该采取什么措施,它们是:
1、REOPEN 指定时间后再次尝试归档
使用REOPEN=seconds(默认=300)属性,在指定时间重复尝试向归档目的地进行归档操作,如果该参数值设置为0,则一旦失败就不会再尝试重新连接并发送,直到下次redo数据再被归档时会重新尝试,不过并不会归档到已经失败的归档目的地,而是向替补的归档目的地发送。
2、ALTERNATE 指定替补的归档目的地
alternate属性定义一个替补的归档目的地,所谓替补就是一旦主归档目的地因各种原因无法使用,则临时向alternate属性中指定的路径写。
需要注意一点,reopen的属性会比alternate属性优先级要高,如果你指定reopen属性的值>0,则lgwr/arch会首先尝试向主归档目的地写入,直到达到最大重试次数,如果仍然写入失败,才会向alternate属性指定的路径写。
3、MAX_FAILURE 控制失败尝试次数
max_failure属性指定一个最大失败尝试次数,大家应该能够联想到reopen,没错两者通常是应该配合使用,reopen指定失败后重新尝试的时间周期,max_failure则控制失败尝试的次数,如例:
LOG_ARCHIVE_DEST_1='LOCATION=E:ora10goradatajsspdg REOPEN=60 MAX_FAILURE=3'
管理归档中断
如果primary数据库中的归档日志没能成功发送至standby数据库,就会出现归档中断。当然通常情况下你不需要担心这一点,因为dg会自动检测并尝试复制丢失的归档以解决中断问题,通过什么解决呢?FAL(Fetch Archive Log)。
FAL分server和client,前面创建步骤中讲初始化参数时想必大家也注意到了。FAL client自动主动要求传输归档文件,FAL server则响应FAL client发送的请求。多好的两口子啊。
FAL机制会自动处理下列类似的归档中断问题:
l 当创建物理或逻辑的standby数据库,FAL机制会自动获取primary数据库热备时产生的归档文件。
l 当接收的归档文件出现下列的问题时,FAL机会会自动获取归档文件解决:
Ø 当接收到的归档在应用之后被删除时;
Ø 当接收到的归档所在磁盘损坏时;
l 当存在多个物理standby时,FAL机制会自动尝试从其它standby服务器获取丢失的归档文件。
让大家了解这个东西不是为了让你做什么,而是希望你放心,oracle会管理好这些,如果它没有管理好,你明白这个原理,你也能分析一下它为什么没能管理好,通过什么方式能够促使它恢复有效管理的能力,当然你一定要自己动手,也可以,下面通过示例来说明手工处理归档中断(注意,俺只描述步骤,演示俺就不做了。因为三思现在用地最大保护模式,不会丢失归档地说,哇哈哈哈:))
1、 首先你要确认一下standby是否存在归档中断
可以通过查询v$archive_gap视图来确定,如果有记录就表示有中断。
SQL> select *from v$archive_gap;
这一步的目的是为了取出对应的LOW_SEQUENCE#和HIGH_SEQUENCE#,如果有RAC的话,还需要注意一下THREAD#。
2、 查找sequence对应的归档文件
SQL> SELECT NAME FROM V$ARCHIVED_LOG WHERE THREAD#=1 AND DEST_ID=1 AND SEQUENCE# BETWEEN 7 AND 10;
3、 复制对应的归档文件到standby
注意,如果是RAC的话,要找对机器哟:)
然后通过alter database register logfile命令将这些文件重新注册一下,例如:
SQL> ALTER DATABASE REGISTER LOGFILE 'e:ora10gjsspdgxxxx.arc';
然后重启redo应用即可。
对于逻辑standby的丢失归档处理稍微复杂一点点,因为逻辑standby没有提供类型v$archive_gap;之类的视图,因此我们需要自己想办法来识别是否存在丢失的情况,具体可以通过下列的语句:
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#;
找出丢失的归档文件后,接着的处理方式与物理standby相同。