在DG中,switchover和failover是两个重要的概念,也是DG实现的核心。两者共同点都是Primary和Standby角色切换,差异在于Planned和UnPlanned之分。Switchover关键点在于Planned,这个切换动作是在运维机构规划范围内的动作。比如,进行定期系统软硬件升级、设备维修等动作。而Failover是真正出现严重系统故障,如数据库宕机、软硬件故障导致的Primary不能支持服务,从而进行的切换动作。
本文参考Oracle 11G在线文档:http://docs.oracle.com/cd/E11882_01/server.112/e10700/role_management.htm#SBYDB00600
SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE; SWITCHOVER_STATUS ----------------- TO STANDBY SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE; SWITCHOVER_STATUS -------------------- SESSIONS ACTIVE
返回值是 TO STANDBY或SESSIONS ACTIVE表明主数据库可以切换到备用库。
SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
如果主库查询的SWITCHOVER_STATUS 返回值为TO STANDBY ,则WITH SESSION SHUTDOWN 字句可以省略。
SQL> SHUTDOWN ABORT; SQL> STARTUP MOUNT; SQL> select database_role from v$database; DATABASE_ROLE ---------------- PHYSICAL STANDBY 前主库的角色现在已经是物理备库了。
在Oracle 11G数据库没必要执行shutdown abort,因为ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN 已经默认关闭了数据库。
SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE; SWITCHOVER_STATUS ----------------- TO_PRIMARY 1 row selected
SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN ; Database altered.
如果原备库SWITCHOVER_STATUS 返回值是 TO_PRIMARY ,则 WITH SESSION SHUTDOWN 字句可以省略。
SQL> ALTER DATABASE OPEN; Database altered. SQL> select database_role from v$database; DATABASE_ROLE ---------------- PRIMARY
SQL> alter database open; Database altered. SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; Database altered. SQL> select PROTECTION_MODE from v$database; PROTECTION_MODE -------------------- MAXIMUM PERFORMANCE
8、重启其它的物理备库上的Redo Apply
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
SQL> alter system switch logfile; System altered. [oracle@dgstandby02 archivelog]$ ls 1_90_889818284.dbf 1_91_889818284.dbf 1_92_889818284.dbf
备库查看
[oracle@dgmaster01 standbylog]$ ls 1_90_889818284.dbf 1_91_889818284.dbf 1_92_889818284.dbf
插入数据
SQL> insert into emp (empno,ename) values (2312,'li'); 1 row created. SQL> commit; Commit complete. 备库查看 SQL> select empno,ename from emp; EMPNO ENAME ---------- ---------- 2312 li
案例一、模拟主库网络不通,这里采用备库开防火墙的方式,阻止主备库通信,让主库的日志无法传输到备库。
[oracle@dgmaster01 archivelog]$ ll 总用量 23052 -rw-r-----. 1 oracle oinstall 37888 9月 28 17:35 1_100_889818284.dbf -rw-r-----. 1 oracle oinstall 28672 9月 28 17:36 1_101_889818284.dbf -rw-r-----. 1 oracle oinstall 1024 9月 28 10:51 1_90_889818284.dbf -rw-r-----. 1 oracle oinstall 641024 9月 28 10:51 1_91_889818284.dbf -rw-r-----. 1 oracle oinstall 225792 9月 28 10:57 1_92_889818284.dbf -rw-r-----. 1 oracle oinstall 21845504 9月 28 17:12 1_93_889818284.dbf -rw-r-----. 1 oracle oinstall 62464 9月 28 17:12 1_94_889818284.dbf -rw-r-----. 1 oracle oinstall 119296 9月 28 17:16 1_95_889818284.dbf -rw-r-----. 1 oracle oinstall 5632 9月 28 17:17 1_96_889818284.dbf -rw-r-----. 1 oracle oinstall 57344 9月 28 17:17 1_97_889818284.dbf -rw-r-----. 1 oracle oinstall 318976 9月 28 17:27 1_98_889818284.dbf -rw-r-----. 1 oracle oinstall 235008 9月 28 17:34 1_99_889818284.dbf [root@dgstandby02 standbylog]# ll 总用量 22440 -rw-r-----. 1 oracle oinstall 1024 9月 28 10:51 1_90_889818284.dbf -rw-r-----. 1 oracle oinstall 641024 9月 28 10:51 1_91_889818284.dbf -rw-r-----. 1 oracle oinstall 225792 9月 28 10:57 1_92_889818284.dbf -rw-r-----. 1 oracle oinstall 21845504 9月 28 17:12 1_93_889818284.dbf -rw-r-----. 1 oracle oinstall 62464 9月 28 17:12 1_94_889818284.dbf -rw-r-----. 1 oracle oinstall 119296 9月 28 17:16 1_95_889818284.dbf -rw-r-----. 1 oracle oinstall 5632 9月 28 17:17 1_96_889818284.dbf -rw-r-----. 1 oracle oinstall 57344 9月 28 17:17 1_97_889818284.dbf
这里看到主库日志序列已经到101,而备库传过来的日志只到97
这个时候我们在强行关闭主库 shutdown abort
Oracle 11G 新特性,如果主库这时候可以到mount状态,可以使用ALTER SYSTEM FLUSH REDO TO target_db_name;
target_db_name 为目标库的DB_UNIQUE_NAME
SQL> ALTER SYSTEM FLUSH REDO TO ‘DGS’;
System altered.
这步完成后,就可以在备库看见新的redo log已经传输到备库了。
[root@dgstandby02 standbylog]# ll 总用量 23052 -rw-r-----. 1 oracle oinstall 37888 9月 28 17:57 1_100_889818284.dbf -rw-r-----. 1 oracle oinstall 28672 9月 28 17:57 1_101_889818284.dbf -rw-r-----. 1 oracle oinstall 1024 9月 28 10:51 1_90_889818284.dbf -rw-r-----. 1 oracle oinstall 641024 9月 28 10:51 1_91_889818284.dbf -rw-r-----. 1 oracle oinstall 225792 9月 28 10:57 1_92_889818284.dbf -rw-r-----. 1 oracle oinstall 21845504 9月 28 17:12 1_93_889818284.dbf -rw-r-----. 1 oracle oinstall 62464 9月 28 17:12 1_94_889818284.dbf -rw-r-----. 1 oracle oinstall 119296 9月 28 17:16 1_95_889818284.dbf -rw-r-----. 1 oracle oinstall 5632 9月 28 17:17 1_96_889818284.dbf -rw-r-----. 1 oracle oinstall 57344 9月 28 17:17 1_97_889818284.dbf -rw-r-----. 1 oracle oinstall 318976 9月 28 17:57 1_98_889818284.dbf -rw-r-----. 1 oracle oinstall 235008 9月 28 17:57 1_99_889818284.dbf
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
这步完成之后,就可以在备库看到刚才的数据已经同步了。
SQL> select empno,ename from emp; EMPNO ENAME ---------- ---------- 1234 liu 2312 li
SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE; SWITCHOVER_STATUS ----------------- TO PRIMARY
SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
SQL> ALTER DATABASE OPEN;
案例2
模拟故障:主库直接宕机
备库采用是归档日志应用方式,不是实施应用方式
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT
主库插入数据:
SQL> begin 2 for i in 1700 .. 2000 3 loop 4 insert into emp (empno,ename) values ( i, 'xxx' ); 5 end loop; 6 commit; 7 end; 8 / PL/SQL procedure successfully completed. SQL> select count(*) from emp; COUNT(*) ---------- 630
查询备库
SQL> select count(*) from emp; COUNT(*) ---------- 329
我们看到数据并没有马上同步过来,只有主库切换日志时,归档才会传输到备库并且应用。
此时我们强制关闭主库
SQL> shutdown abort;
此刻查询备库数据
SQL> select count(*) from emp; COUNT(*) ---------- 329
如果故障不严重,主库仍可访问,可以考虑从步骤1开始做起,但如果故障比较严重,主库已完全不能访问,直接从第5步开始做起。
Oracle 11G 新特性,如果主库这时候可以到mount状态,可以使用ALTER SYSTEM FLUSH REDO TO target_db_name;
target_db_name 为目标库的DB_UNIQUE_NAME
这个语句将任何未寄出的REDO LOG 从主数据库到备用数据库,并等待重新被应用到备用数据库。
SQL> ALTER SYSTEM FLUSH REDO TO 'DGS'; System altered.
如果这条语句没有返回任何错误,可以直接进行第5步操作。
SQL> SELECT UNIQUE THREAD# AS THREAD, MAX(SEQUENCE#) OVER (PARTITION BY thread#) AS LAST from V$ARCHIVED_LOG; THREAD LAST ---------- ---------- 1 100
如果可能的话,复制主库未传输到备库的redo log,并注册它
SQL> ALTER DATABASE REGISTER PHYSICAL LOGFILE 'filespec1';
SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP; THREAD# LOW_SEQUENCE# HIGH_SEQUENCE# ---------- ------------- -------------- 1 90 92
拷贝备库上缺失的redo log 并注册它
SQL> ALTER DATABASE REGISTER PHYSICAL LOGFILE 'filespec1';
如果不能弥补这些日志的差距,那么将会有数据丢失。
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
如果没有返回任何错误,直接进行第7步
如果发生错误,并且重复第3、第4步骤仍然不能解决,仍然可以继续故障切换(数据丢失),请执行下边的语句。
SQL> ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE;
如果完成了ACTIVATE,直接进行第9步。
SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE; SWITCHOVER_STATUS ----------------- TO PRIMARY 1 row selected
SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
SQL> ALTER DATABASE OPEN;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
当我做完故障转移时,查看库数据是630条,也就是说没有数据丢失,因为我用的的是lgwr方式,不是arch方式,这只是测试环境由于数据量不大,实际生产环境可能就没这么好运了。