Skip to content

Oracle dataguard 日志缺失的解决办法

归档日志间隙(Archive Gap)

 

归档日志间隙是在 Standby 端一系列丢失的重做日志,导致日志应用服务无法继续运行。这通常发生在 Standby 端无法从 Primary Database 接收重做日志或重做日志在 Standby Database 上不可用时。常见原因有:

  • 网络连接断开或者日志传输服务停止
  • Standby Database 不可用
  • 日志传输服务的配置错误
  • Standby 端的 IO 问题
  • 归档日志在应用到 Standby 前被手工删除
  • Primary 和 Standby 之间的网络带宽不足

一旦在 Standby Database 上存在归档间隙,Log Apply Services 就会卡住,直到日志间隙(Gap)被解决,例如。丢失的 Redo 被重新获取并且在 Standby 端可用。然后,日志应用服务可以选中它并继续处理。

 

解决日志间隙的方式

 

有4种方案来解决 Standby Database 上的日志间隙。这些方案在下面讨论。

自动日志间隙解决方案

自动日志间隙解决方案是由日志传输服务自动进行的。它会把当前正在传输的日志和最近收到的日志进行对比,如果有不匹配的情况出现,Standby 端的 RFS 进程就会检测到并自动发送 ARCH-RFS 心跳 Ping 请求来要求发送丢失的日志。这种类型的日志间隙解决方法使用了主数据库上的 log_archive_dest_n 中定义的 Service。另外 ARCH-RFS 心跳 Ping 可以通过对当前的日子序列号进行查询来检测日志间隙。如果存在日志间隙则仍通过ARCH-RFS 心跳 Ping 请求来解决它。在问题得到解决后,会通知日志传输进程(ARCH 或者 LGWR)。对于自动日志间隙解决方案,不需要额外的设置或者监控。

 

FAL (Fetch Archive Log)日志间隙解决方案

当一个归档日志在 Standby 数据库上被收到或者归档,它就会被注册到 Standby 的控制文件中。(您可以在物理 Standby 数据库上查询 v$archived_log 或在逻辑 Standby 数据库上查询 dba_logstdby_log 来获取这些注册信息)。如果这个文件因为某些原因丢失或者损坏(比如,它被意外删除),FAL 就会被调用来解决日志间隙问题。因为这些缺失的日志文件通常由 Standby 数据库上的日志应用服务检测到。它独立于日志传输服务,并且没有和主库之间的直接链接。要使用 FAL,必须在 Standby 数据库设置一个或者两个(11.2.0 之前的版本)初始化参数:

FAL_SERVER:设置 Oracle Net Service Name(TNS-Alias 或者 Connect Descriptor)指向用来获取丢失的归档日志的数据库。它可以是一个 Data Guard 环境的主库,或者是另一个备库,ArchiveLog Repository- 或者 Far Sync Standby (> Oracle 12.1.0) Database。可以指定多个 Service Names(逗号分隔)。FAL 会顺序的尝试这些数据库来解决日志间隙问题。

FAL_CLIENT (< Oracle 11.2.0):在 FAL_SERVER 数据库上设置 Oracle Net Service Name(TNS-Alias 或 Connect Descriptor)指向接收 REDO 的 Standby 数据库(比如,它是 FAL_SERVER 数据库需要发送 REDO 到的目标数据库)。确保这个 TNS-Alias 存在于 FAL_SERVER 数据库的 TNSNAMES.ORA 文件中。从 Oracle 11.2.0 开始,这个参数不再需要。但是需要确保 FAL_SERVER 数据库存在一个log_archive_dest_n 指向要解决日志间隙问题的 Standby 数据库。

当 Log ApplyServices 检测到日志间隙问题,它会发送一个 FAL 请求把 FAL_CLIENT 信息(Version > 11.1.0 则为 db_unique_name)给 FAL_SERVER。一个 FAL_SERVER 数据库上的 ARCH-Process 会尝试获取那个日志并发送回 FAL_CLIENT(或者 db_unique_name 对应的 Destination)。如果第一个 FAL_SERVER 无法解决日志间隙,会尝试列表中的下一个 FAL_SERVER。如果所有的 FAL_SERVERs 都无法解决,那么 FAL 请求会失败,并且一个对应的错误信息会写入对应 Standby 数据库的 ALERT.LOG。

为了成功解决日志间隙问题,需要的归档日志应当存在于 FAL_SERVER 数据库(存在于磁盘并且对应的信息同时存在于控制文件中)。

FAL 从 Oracle 9.2.0 开始可用于物理 Standby 数据库,从 Oracle 10.1.0 开始可用于逻辑 Standby 数据库。

 

手工解决日志间隙

如果日志间隙问题不能被上面提到方式解决,那么可以尝试手工解决。

可以通过查询物理 Standby 数据库的 $archive_gap 或者逻辑 Standby 数据库的 dba_logstdby_log 来确定当前的归档日志间隙,例如:

 

物理 Standby 数据库

SQL> select * from v$archive_gap;

逻辑 Standby 数据库

SQL> select thread#, sequence# from dba_logstdby_log l where next_change# not in

(select first_change# from dba_logstdby_log where l.thread#=thread#)

order by thread#, sequence#;

 

现在复制缺失的特定编号的 redo 日志到 Standby 数据库的对应位置。如缺失的日志尚未注册到 Standby 数据库,需要先注册它们才能让 Log Apply Services 处理这些日志文件。可以使用下面的命令注册:

物理 Standby:

SQL> alter database register logfile ‘<File-Specification>’;

逻辑 Standby:

SQL> alter database register logical logfile ‘<File-Specification>’;

 

在它们被注册后,Log Apply Services 就可以处理了。

 

使用增量备份前滚(仅适用于物理 Standby)

如果日志间隙无法被上面提到的方式解决,间隙太大需要太久时间才能解决或者丢失的日志无法被找到,您仍然可以通过使用 SCN 增量备份来前滚物理 Standby 数据库。这个功能从 Oracle 10.2.0 开始可以使用。这个功能通过记录最后应用到 Standby 数据库的SCN,然后使用 RMAN 以及当前控制文件的备份来对主库创建一个从那个 SCN 开始的增量备份。

之后首先用增量备份中的控制文件替换 Standby 的控制文件,之后应用增量备份到 Standby 数据库。这是一个把 Standby 数据库同步到最新的主库的状态的最快最简单的方式。因为采取的步骤各个版本都不同