总体思想:

尽可能的将主库的日志传输到备库,然后 CANCEL REDO APPLYING ---> STOP REDO APPLYING ---> SWITCH TO PRIMARY, 如果有日志缺失不能解决,则将备库强制激活。

Step 1 :将主库的日志传输到备库(如果可以mount的话)

如果主库能启动到 mount 阶段,在主库上执行如下命令将未发送到 standby 的 archived 和 online redo 发送到 standby:

SQL> ALTER SYSTEM FLUSH REDO TO target_db_name;
target_db_name 是指 standby 的 DB_UNIQUE_NAME

如果该步操作能够正常完成,则可以零数据丢失。正常,go to setup5。
如果不能 mount,或者上面的命令有任何报错,或者因为不想等待中断了上面的命令,go to step2。

Step 2 :保证备库拥有主库最新的归档日志(each thread)

在 primary 和 standby 上都执行如下查询,检查各自的最高的日志序列号:

SQL>  SELECT UNIQUE THREAD# AS THREAD, MAX(SEQUENCE#) OVER (PARTITION BY thread#) AS LAST from V$ARCHIVED_LOG;

    THREAD     LAST
---------- ----------
     1     1493
     2     1094

在 standby 上面执行如下命令检查缺失的日志:
 
SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;

THREAD#    LOW_SEQUENCE# HIGH_SEQUENCE#
---------- ------------- --------------
         1            1487          1491     

LOW_SEQUENCE#, HIGH_SEQUENCE# 分别表示缺少的最小和最大归档日志序号。

注意:可能会查询 GAP 没有,但是最大日志序号 standby 小于 primary(即有最新的归档没有传输过来)。

尽最大可能将不全的日志从 primary 传输到 standby,然后使用如下命令进行注册:

SQL> ALTER DATABASE REGISTER PHYSICAL LOGFILE 'filespec1';

重复上面的步骤直至所有日志缺失都得到解决。如果不能解决所有缺失的日志,则 Failover 会丢失数据。

Step 3 :Stop Redo Apply.

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

Step 4 :Finish applying all received redo data.

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;

如果命令没有报错,proceed to Step 5.
如果有报错,尝试解决造成报错的原因,再次执行上面的命令,直至成功执行,然后 proceed to Step 5.

如果报错不能得到解决(例如日志缺失不能修复),此时只能将备库强制激活为主库(with some data loss) :

SQL> ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE;
SQL> ALTER DATABASE OPEN;

Step 5 :检查 standby 已经准备好成为主库

SQL> SELECT SWITCHOVER_STATUS FROM GV$DATABASE;

SWITCHOVER_STATUS
-----------------
TO PRIMARY
SESSIONS ACTIVE

Step 6 : 将 standby 切换为 primary

SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;

Step 7 :打开新主库

SQL> ALTER DATABASE OPEN;
-- By 许望(RHCA、OCM、VCP)
最后修改:2019 年 12 月 14 日 03 : 43 PM
如果觉得我的文章对你有用,请随意赞赏