自学内容网 自学内容网

Oracle 11g Data Guard 环境中的 GAP 处理办法

概述

在Data Guard 环境中,当主库的某些日志没有成功传送到备库时,就会发生归档裂缝(Archive Gap)。目前,Oracle 提供了两种日志 GAP 的检测和处理机制:自动 GAP 处理(Automatic Gap Resolution)和 FAL 进程 GAP 处理(FAL Gap Resolution)。

  • 自动 GAP 处理:主库上的 ARCn 进程会每分钟检查备库上的日志 GAP 情况并做相应处理。
  • FAL 进程 GAP 处理:通过配置 FAL_SERVER 和 FAL_CLIENT 实现 GAP 检测的一种机制,备库主动发起“取”日志的过程。FAL 进程只在物理备库存在,该进程只有在需要的时候才会启动,工作完成后关闭。

大致可以分为以下几种情况来处理:

  1. 主库归档日志存在:可以通过配置 Fetch Archive Log (FAL) 参数,自动解决归档 GAP,或将归档日志拷贝到从库手工注册处理。
  2. 主库归档日志丢失:需要人工干预来修复,11G具体步骤如下:
    1. 以备库的当前 SCN 号为起点,在主库上做一个增量备份。
    2. 在主库上创建一个备库的控制文件。
    3. 将增量备份拷贝到备库上。
    4. 使用新的控制文件将备库启动到 mount 状态。
    5. 将增量备份注册到 RMAN 的 catalog,取消备库的恢复应用,恢复增量备份。
    6. 开启备库的恢复进程。
处理 GAP 方法 1:手动拷贝归档到备库进行手工注册处理(归档未丢失)
(一)物理 DG 手动解决 GAP

在一些特殊情况下,如果 GAP 不能自动解决,那么就需要手工执行中断恢复。通过查询视图 V$ARCHIVE_GAP 可以确定断档的是哪些日志。

-- 查询 GAP
SQL> SELECT * FROM V$ARCHIVE_GAP;

假设当前物理备库丢失日志文件从线程 1 的序号 10 到序号 12。接下来确定归档日志文件的路径(假设在主数据库上的本地归档目的地是 LOG_ARCHIVE_DEST_1):

-- 确定归档日志文件路径
SQL> SELECT NAME FROM V$ARCHIVED_LOG WHERE THREAD#=1 AND DEST_ID=1 AND SEQUENCE# BETWEEN 10 AND 12;

接下来,将这些日志文件拷贝到物理备库,然后在物理备库上使用 ALTER DATABASE REGISTER LOGFILE 语句来注册这些归档日志:

-- 注册归档日志
SQL> ALTER DATABASE REGISTER LOGFILE '/arch/thread1_dest/arch_1_10.arc';
-- 或者
SQL> ALTER DATABASE REGISTER OR REPLACE LOGFILE '/arch/thread1_dest/arch_1_10.arc';
SQL> ALTER DATABASE REGISTER OR REPLACE PHYSICAL LOGFILE '/arch/thread1_dest/arch_1_11.arc';

在物理备库上注册这些日志文件之后,重新打开重做应用进程。如果断档的归档日志较多,可以使用以下 SQL 语句来生成要执行的 SQL 语句(也适用于逻辑 DG):

SELECT 'ALTER DATABASE REGISTER OR REPLACE LOGICAL LOGFILE ''/arch/thread1_dest/arch_1_' || a || '.arc'';' LOGICAL_DG,
       'ALTER DATABASE REGISTER OR REPLACE LOGFILE ''/arch/thread1_dest/arch_1_' || a || '.arc'';' PHYSICAL_DG
FROM (SELECT LEVEL A FROM DUAL CONNECT BY LEVEL <= 12)
WHERE A >= 10;
(二)逻辑 DG 手动解决 GAP

在逻辑备库上查询 DBA_LOGSTDBY_LOG 视图可以确定是否有归档中断。例如,下面的查询指出断档号为 16 至 18:

-- 查询断档日志
SQL> COLUMN FILE_NAME FORMAT a60
SQL> SELECT THREAD#, SEQUENCE#, FILE_NAME
  2  FROM DBA_LOGSTDBY_LOG L
  3  WHERE NEXT_CHANGE# NOT IN (SELECT FIRST_CHANGE# FROM DBA_LOGSTDBY_LOG WHERE L.THREAD# = THREAD#)
  4  ORDER BY THREAD#, SEQUENCE#;

接下来将丢失的日志文件拷贝到逻辑备库,并在逻辑备库上使用 ALTER DATABASE REGISTER LOGICAL LOGFILE 来注册这些日志文件。例如:

-- 注册日志文件
SQL> ALTER DATABASE REGISTER LOGICAL LOGFILE '/arch/oracle/arch_1_16.arc';

在逻辑备库上注册这些日志文件之后,重启 SQL 应用。和物理 DG 一样,在逻辑备库上的 DBA_LOGSTDBY_LOG 视图只返回当前妨碍 SQL 应用继续的下一个中断。在解决指定的中断并重启 SQL 应用之后,再次在逻辑备库上查询 DBA_LOGSTDBY_LOG 视图,以确定下一个中断序号,重复这个过程直到没有更多的中断。

需要注意的是,如果需要的归档日志已经不在主库上了,但是有归档日志的 RMAN 备份,那么可以通过 RMAN 恢复把缺少的归档日志进行还原,如下所示:

-- 设置归档日志目标位置
SET ARCHIVELOG DESTINATION TO '/arch';

-- 恢复归档日志
RESTORE ARCHIVELOG FROM LOGSEQ 17;

处理GAP方法2:主库基于SCN的增量备份来恢复DG(归档丢失)

如果断档的归档日志已经丢失,且RMAN又没有备份,那么在Oracle 10g之前没有办法修复了,只能重建DG,但是从Oracle 10g开始可以采用主库基于SCN的增量备份来恢复DG。

下面我们通过实验来进行展示11g环境中基于SCN的增量备份来恢复DG(常规办法):

示例

首先,模拟备库断电,主库切几个最新的归档,然后手工删掉,重新开启 DG 同步。

备库操作
-- 停止备库的 redo apply
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

-- 关闭备库
SHUTDOWN IMMEDIATE;
主库操作
-- 切换多个日志
ALTER SYSTEM SWITCH LOGFILE; -- 多次执行

-- 删除最近几个归档日志
rm 1_30_1070147166.arc
rm 1_31_1070147166.arc
备库操作
-- 启动备库
STARTUP

-- 使用当前日志文件恢复
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
查看 GAP
-- 查看 GAP
SQL> SELECT * FROM V$ARCHIVE_GAP;

-- 查看已应用的最大序列号
SQL> SELECT MAX(SEQUENCE#) FROM V$ARCHIVED_LOG WHERE APPLIED='YES';

-- 查看备库的状态
SQL> SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY;

假设当前 GAP 为 32-34,下面是具体的处理步骤:

  1. 以备库的当前 SCN 号为起点,在主库上做一个增量备份

    • 备库:

      SELECT TO_CHAR(CURRENT_SCN) FROM V$DATABASE;
      
    • 主库:

      rman target /
      RUN
      {
        ALLOCATE CHANNEL C1 TYPE DISK;
        ALLOCATE CHANNEL C2 TYPE DISK;
        ALLOCATE CHANNEL C3 TYPE DISK;
        ALLOCATE CHANNEL C4 TYPE DISK;
        BACKUP AS COMPRESSED BACKUPSET INCREMENTAL FROM SCN 16010653817 DATABASE FORMAT '/backup/incre_db_%d_%T_%s.bak';
        BACKUP CURRENT CONTROLFILE FOR STANDBY FORMAT '/backup/standby.ctl';
        RELEASE CHANNEL C1;
        RELEASE CHANNEL C2;
        RELEASE CHANNEL C3;
        RELEASE CHANNEL C4;
      }
      
  2. 在主库上创建一个备库的控制文件(前面备份集已经备份这里可以不用做)

    ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/backup/standby.ctl';
    
  3. 将增量备份拷贝到备库上

    scp /backup/incre_* oracle@STANDBY:/backup/
    scp /backup/standby.ctl oracle@STANDBY:/backup/
    
  4. 使用新的控制文件将备库启动到 mount 状态

    SHUTDOWN IMMEDIATE;
    STARTUP NOMOUNT;
    rman target /
    RESTORE CONTROLFILE FROM '/backup/standby.ctl';
    ALTER DATABASE MOUNT;
    
  5. 增量备份注册到 RMAN 的 catalog,取消日志应用,恢复增量备份

    ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
    rman target /
    CATALOG START WITH '/backup/';
    RECOVER DATABASE NOREDO;
    
  6. 备库开启日志同步进程

    sqlplus / as sysdba
    ALTER DATABASE OPEN READ ONLY;
    ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
    

    主库重新激活同步:

    sqlplus / as sysdba
    ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=defer;
    ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=enable;
    

    查询是否存在 GAP,确认主备是否同步:

    sqlplus / as sysdba
    SELECT * FROM V$ARCHIVE_GAP;
    SELECT MAX(sequence#) FROM v$archived_log WHERE applied='YES';
    

至此,DG GAP 已被修复,以上方式为常规修复方式,各个版本都通用。

总结

到这里,12c版本之前的常规处理GAP 问题应该得到了解决。 后面我们会继续整理从12c开始使用RECOVER … FROM SERVICE的方法以及从18c开始使用RECOVER STANDBY DATABASE FROM SERVICE的方法来处理 GAP 办法。


原文地址:https://blog.csdn.net/u010674953/article/details/144219149

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!