9.2.5
首先,data guard的原理是primary DB 将所有操作产生的redo log 传输到standby DB上,再由standby DB对此进行应用。从而产生一个一致的standby DB。在data guard中,存在两类SYNC和ASYNC,下面分别描述两类的工作方法,从而进一步认识它的原理。
SYNC和ASYNC模式的流程
(1)当user发出commit命令后,将产生一条 redo record(也称作redo entry)放入SGA中的 redo buffer中,后台进程LGWR将读取此redo record,将其写入online redo log file,并等待从LNS进程传来的确认信息。
(2)LNS(Log Network Server) 进程同样从redo log buffer读取redo record,并将其通过Oracle Net Services传输给standby DB。在standby DB上的RFS后台进程将接收到的redo record写入standby database中。
(3)当RFS确定写入所有的redo record到磁盘后,向primary DB的LNS发送确认信息。当LGWR收到LNS转发的确认信息后,才返回commit成功的消息给user。
接下来看ASYNC,类似于SYNC,只是primary DB上的LGWR可以不必等待LNS的确认信息,而且LNS可以读取online redo log中的redo record。对于ASYNC,可以考虑使用压缩方式传输redo record,从而节省带宽,但是这会使CPU的利用升高。此外,如果LNS在读取online redo log中记录时刚好遇到online switch或者网络中断,造成Primary Database的某些日志没有成功发送到Standby Database,则可能造成standby的archivelog gap。LNS的不同步记录,在提高性能的同时也可能会产生数据的丢失。
对于redo log的GAP的处理,Oracle的data guard有自己的自动处理方法。log file gap主要出现在primary DB上不断有事务被提交,同时,LNS可能由于网络或是standby DB的问题不能及时同步造成的。此时,primary DB会继续运行,循环使用redo logs,并进行归档。Data Guard会在primary DB上使用一个ARCH进程不断的ping standby DB。当与standby DB可以进行通信时,ARCH的ping进程会通过RFS查询standby的控制文件,获得上一次完成log同步的SCN从而确定从哪一个归档log开始进行同步,从而填补GAP。当完成这一步,会自动过渡到从当前的日志文件中同步。
在Oracle 9i之前处理措施便是设置fal_server和fal_client,从Oracle 9i开始,Oracle提供了两种log gap的检测和处理机制。对于GAP的处理,fal_*参数在某些情况下并不是必须配置的。
1.Automatic Gap Resolution
从Oracle 9i开始,Dataguard就引入了自动日志缺失检测的机制,无须设置任何fal_*参数,Dataguard便运行在这种机制下。当Lgwr和Arch进程发送redo/archive到standby端的时候,当前log sequence会同standby端RFS进程上次接收到的log sequence做比较,如果发现二者有断档,RFS会发送请求到primary端,要求主库传送缺失的日志。从Oracle 9i R2开始,Automatic gap resolution 功能上得到增强。主库上的arch进程会每分钟检查备库上的日志GAP情况并做相应处理。
2.FAL Gap Resolution
FAL是Fetch Archive Log的缩写,从FAL 这个名字可以看出,这个过程是Standby Database主动发起的"取"日志的过程,通过配置FAL server和FAL client实现GAP检测的一种机制。Standby Database 就是FAL_CLIENT。它是从FAL_SERVER中取这些GAP,Oracle 10g中,这个FAL_SERVER可以是Primary Database,也可以是其他的Standby Database。
FAL_SERVER发送请求,FAL_SERVER通过网络向FAL_CLIENT发送缺失的日志,但是这两个连接不一定是一个连接。 因此FAL_CLIENT向FAL_SERVER发送请求时,会携带FAL_CLIENT参数值,用来告诉FAL_SERVER应该向哪里发送缺少的日志。这个参数值也是一个Oracle Net Name,这个Name是在FAL_SERVER上定义的,用来指向FAL_CLIENT。
在Oracle 9i R2以上版本中,Oracle首先尝试使用FAL Gap Resolution进行GAP处理,当发现FAL机制并没有配置生效的时候,进而尝试使用Automatic Gap Resolution进行处理。
对于一些cascade dataguard架构,FAL Gap Resolution是更好的GAP处理方式。另外,Automatic gap resolution 在某些版本的dg环境下存在bug(比如bug 5929647等),不得不配置FAL参数。
在一些情况下,自动中断恢复可能不会发生,需要手工执行中断恢复。例如,如果使用逻辑备数据库并且主数据库不可用时,将需要手工执行中断恢复。下面描述了如何查询适当的视图,以确定哪个日志文件丢失了并且执行手工恢复。
第1步:在物理备数据库检查归档中断
要确定在物理备数据库上是否有归档中断,查询V$ARCHIVE_GAP 视图,如下面例子所示:
- SQL>
SELECT * FROM V$ARCHIVE_GAP; - THREAD#
LOW_SEQUENCE# HIGH_SEQUENCE# - -----------
------------- -------------- - 1
7 10
- SQL>
SELECT NAME FROM V$ARCHIVED_LOG WHERE THREAD#=1 AND DEST_ID=1 - 2>
AND SEQUENCE# BETWEEN 7 AND 10; - NAME
- -----------------------------------------------------------------
- /primary/thread1_dest/arcr_1_7.arc
- /primary/thread1_dest/arcr_1_8.arc
- /primary/thread1_dest/arcr_1_9.arc
第2步:复制这些日志文件到物理备数据库
在物理备数据库上使用 ALTER DATABASE REGISTER LOGFILE
语句来注册它们。
- SQL>
ALTER DATABASE REGISTER LOGFILE - '/physical_standby1/thread1_dest/arcr_1_7.arc';
- SQL>
ALTER DATABASE REGISTER LOGFILE - '/physical_standby1/thread1_dest/arcr_1_8.arc';
9.2.5LOG GAP检测和解决(2)
在物理备数据库上注册这些日志文件之后,重启重做应用。
注:
物理备数据库上的V$ARCHIVE_GAP 固定视图只返回当前妨碍重做应用继续的下一个中断。在解决中断并重启重做应用后,再次在物理备数据库上查询V$ARCHIVE_GAP 固定
视图来确定下一个中断序号,如果有的话。重复这个过程直到没有更多的中断。
第3步:在逻辑备数据库上要确定是否有归档中断
要确定是否有归档中断,在逻辑备数据库上查询DBA_LOGSTDBY_LOG 视图。例如,下面的查询指出在归档重做日志文件的序号中有中断,因为它在逻辑备数据上对于THREAD1 显示有两个文件。(如果没有中断的话,查询应该每个线程只显示一个文件。)输出显示最高的注册文件是序列号10,但是在所示文件序列号6 有中断:
第4步:在逻辑备数据库上注册丢失的归档日志
复制丢失的日志文件,序列号 7、8 和9,到逻辑备系统,并在逻辑备数据库上使用ALTER DATABASE REGISTER LOGICAL LOGFILE 语句来注册它们。例如:
在逻辑备数据库上注册这些日志文件之后,重启SQL应用。
注:
在逻辑备数据库上的DBA_LOGSTDBY_LOG 视图只返回当前妨碍SQL 应用继续的下一个中断。在解决指定的中断并重启SQL应用之后,再次在逻辑备数据库上查询DBA_LOGSTDBY_LOG视图,以确定下一个中断序号,如果有的话,重复这个过程直到没有更多的中断。
- SQL>
ALTER DATABASE REGISTER LOGICAL LOGFILE - '/disk1/oracle/dbs/log-1292880008_10.arc';
- SQL>
COLUMN FILE_NAME FORMAT a55 - 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#; - THREAD#
SEQUENCE# FILE_NAME - ---------
---------- --------------------------------------------- - 1
6 /disk1/oracle/dbs/log-1292880008_6.arc - 1
10 /disk1/oracle/dbs/log-1292880008_10.arc