总体思想:
尽可能的将主库的日志传输到备库,然后 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;