Physical Standby Database Failover

时间:2021-11-23 11:58:18

1、物理standby failover 切换

故障转移时在一些糟糕的事情发生时执行的计划外事件,需要将生产库移动到DR站点。有意思的是,这时候人们通常忙来忙去,试图弄明白发生了什么,需要做些什么才能使数据库恢复过来。客户打来电话询问系统核实才能恢复,高级管理人员在走廊徘徊,追究是谁范了错误。对于DBA来说,没有什么事情比时空的备用站点更可怕,并且在需要备用站点前,我们也不知道它是否奏效。如果故障转移失败,DBA们将会失去奖金,甚至职业生涯因此中断。

所以我们在系统建立初期,就要有周密的后援计划。一旦出现问题,做到手不忙,心不慌。大显身手的时候到了。但此前需要有一番详尽实验做支撑,亲自动手很重要!

Step 1冲刷任何没有从主数据库发送到备用数据库的的重做

如果主数据库不能被Mounted,那可能就要将没有发送的归档和当前的日志从主库发送到备用数据库。如果这个操作时成功的,零数据丢失将是可能的,即使它没有在最大保护模式中。

确信redo apply是活动的在目标备用数据库上。

Mount,不要要打开主数据库。如果主数据库不能被mounted,跳至step 2.

执行如下SQL语句在primary database:

SQL> ALTER SYSTEM FLUSH REDO TO target_db_name;

Target_db_name为目标备份库的DB_UNIQUE_NAME,它将会受到冲刷过来的重做。该语句只在11G R2中被支持。

如果该语句完成却没有错误,跳至step 5.如果执行过程出错,或者它没有有停下,因为你不能等待很长时间直到这个语句执行完,继续 step 2.

Step 2核实备份库中最近从主数据库发送过来的归档日志文件。

查询V$ARCHIVED_log视图在目标备份库中,获取每个线程实例归档过来的最大序列号。

例如:

SQL> SELECT UNIQUE THREAD# AS THREAD, MAX(SEQUENCE#) over(partition by thread#) as last from v$archived_log;

THREAD      LAST

---------- ----------

1            517

2            412

如果可能,拷贝每个主数据库归档重做日志到备份库,如果那些日志不在备份库上。并且注册它。它必须被做在每个重做线程上。

例如:

SQL> ALTER DATABASE REGISTER PHYSICAL LOGFILE '<from your list>';

Step 3认定和处理任何的归档重做日志间隔(archived redo log gaps)

查询V$archive_gap视图在目标备份库上,决定这是否有任何的重做间隔。

For example:

SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;

THREAD#   LOW_SEQUENCE# HIGH_SEQUENCE#

---------- ------------- --------------

1           90             92

可以看到存在重做间隔,需要线程1归档来的90、91、92号日志,如果可能,拷贝这些缺失的归档重做文件到目标重做数据库上。然后在每个线程节点上注册他们。

SQL> ALTER DATABASE REGISTER PHYSICAL LOGFILE 'filespec1';

Step 4重复步骤3直到重做间隔被解决

步骤3中仅仅是最高的间隔。在解决间隔后,你必须重复这个查询直到间隔没有。

如果间隔没有被解决,一些数据的丢失将会丢失在故障转移期间。

Step 5停止Redo Apply

执行如下SQL语句在目标备份库上:

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

Step 6完成所有重做数据的应用

执行如下SQL语句在目标备份库上:

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;

如果该语句执行没有错误,行进到Step 7.

如果错误发生,一些接受到的重做数据没有被应用。尝试解决这些错误的原因并且重新确定这些错误状态在行进至下一步之前。

如果错误状况不能解决,故障切换也能进行(伴随一些数据丢失),执行下列SQL语句在standby databse:

SQL> ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE;

此时是进行强制的切换,跳至步骤9,当这个激活状态被完成了。

Step 7确定目标备份库已经准备变成了一个主数据

执行如下语句确认数据库状态:

SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;

SWITCHOVER_STATUS

-----------------

TOPRIMARY

1 row selected

如果这个值是TOPRIMARY或者SESSIONS ACTIVE表明主数据库是可以切换成Standby role的。如果是其他的值将不可以执行切换,

Step 8切换物理备份库到主数据库角色

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

Step 9打开新的主数据库

SQL> ALTER DATABASE OPEN;

Step 10备份新的主数据库

Oracle推荐对新的主数据库做一个全库备份。

Step 11在物理standby database上重启Redo Apply

For example:

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE -

> DISCONNECT FROM SESSION;

Step 12在可选择的情况下,重建失败的主数据库。

在故障切换后,源主数据库可能转换成一个物理standby数据库或者从新的主数据库的备份重建。

一旦源主数据库以Standby Role在运行,一次切换又可以把它重建回Primary role。

2、FAILOVER切换实录

SQL> alter system flush redo to 'HAINAN';

alter system flush redo to 'HAINAN'

*

ERROR at line 1:

ORA-16442: ALTER SYSTEM FLUSH REDO TO STANDBY succeeded, but some redo has not

been applied.

以上的步骤要花费N久的时间等待。

查看主备库上的alert日志:

主库上有大量的如下日志:

Fri Jul 12 11:23:22 2013

ARC4: Archiving disabled

LOG_ARCHIVE_DEST_2 is a potential flush redo target

LOG_ARCHIVE_DEST_2 is a potential flush redo target

LOG_ARCHIVE_DEST_2 is a potential flush redo target

LOG_ARCHIVE_DEST_2 is a potential flush redo target

备库上有如下的大量日志:

Fri Jul 12 11:23:30 2013

Standby switchover readiness check: Checking whether recoveryapplied all redo..

Physical Standby applied all the redo from the primary.

Standby switchover readiness check: Checking whether recoveryapplied all redo..

Physical Standby applied all the redo from the primary.

由此可见,应该是主库对备库的每个归档进行校验,要花费大量时间的。所以在系统建立初期,就要考虑的两条重要信息是公司需要实现的恢复点目标(recovery point objective,RPO)和恢复时间目标(recovery time objective,RTO)。

虽然看到了succeeded字样,但还是按照有错误处理,官网搜索了ORA-16442下,竟然没有结果,新特新还是有缺点的,往下走。

SQL> SELECT UNIQUE THREAD# AS THREAD, MAX(SEQUENCE#) over(partition by thread#) as last from v$archived_log;

THREAD      LAST

---------- ----------

2            415

1            519

SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;

no rows selected

主库上查询,得到同样的结果,说明日志均被应用,由于我应用了standby log,并且开启了real time 应用,实际中丢失数据的概率大大被降低了,这也是oracle推荐的用法。

SQL> SELECT UNIQUE THREAD# AS THREAD, MAX(SEQUENCE#) over(partition by thread#) as last from v$archived_log;

THREAD      LAST

---------- ----------

2            415

1            519

备库上继续执行如下操作:

SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;

no rows selected

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

Database altered.

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;

Database altered.

SQL> ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE;

Database altered.

SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;

SWITCHOVER_STATUS

--------------------

NOT ALLOWED

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

ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN

*

ERROR at line 1:

ORA-01109: database not open

SQL> select status from V$instance;

STATUS

------------

MOUNTED

SQL> alter database open;

Database altered.

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

ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN

*

ERROR at line 1:

ORA-16109: failed to apply log data from previous primary

SQL> select status from V$instance;

SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;

SWITCHOVER_STATUS

--------------------

FAILED DESTINATION

SELECT SWITCHOVER_STATUS,OPEN_MODE,DATABASE_ROLE,PROTECTION_MODE FROM V$DATABASE;BASE;

SWITCHOVER_STATUS   OPEN_MODE                    DATABASE_ROLE    PROTECTION_MODE

-------------------- -------------------- ---------------- --------------------

FAILED DESTINATION  READ WRITE        PRIMARY           MAXIMUM PERFORMANCE

查看最初的是NOT ALLOWED,切换后变成了FAILED DESTINATION,但数据库可以write并且是primary的了。

重启数据库:

SQL> startup force

ORACLE instance started.

Total System Global Area 943669248 bytes

Fixed Size                                2234000 bytes

Variable Size                        264243568 bytes

Database Buffers               671088640 bytes

Redo Buffers                          6103040 bytes

Database mounted.

Database opened.

SQL> select status from v$instance;

STATUS

------------

OPEN

查看alert日志:

Fri Jul 12 14:05:14 2013

PING[ARC5]: Heartbeat failed to connect to standby 'beijing'. Error is 16009.

PING[ARC5]: Heartbeat failed to connect to standby 'beijing'. Error is 16009.

PING[ARC5]: Heartbeat failed to connect to standby 'beijing'. Error is 16009.

Fri Jul 12 14:06:14 2013

PING[ARC5]: Heartbeat failed to connect to standby 'beijing'. Error is 16009.

PING[ARC5]: Heartbeat failed to connect to standby 'beijing'. Error is 16009.

出现大量的ORA-16009错误,它不断的去尝试连接beijing这个standby database,由于我做的是failover,此时standby是关闭的。

SQL> show parameter log_archive_dest_2

NAME                                                       TYPE           VALUE

------------------------------------  ----------- ------------------------------

log_archive_dest_2                              string         SERVICE=beijing ASYNC VALID_FO

R=(ONLINE_LOGFILES,PRIMARY_ROL

E) DB_UNIQUE_NAME=beijing

SQL> alter system set log_archive_dest_2='' scope=spfile;

System altered.

SQL> startup force

SQL> show parameter log_archive_dest_2

NAME                                                       TYPE           VALUE

------------------------------------ ----------- ------------------------------

log_archive_dest_2                              string

取消远程归档路径,错误消除。