年底了很多客户都在借着银监的窗口进行容灾切换演练。这两年有一个明显的趋势,就是监管对容灾的要求越来越高。早些年的容灾通常是摆设,只需要解决有的问题,至于能不能切过去,切过去能不能顶得住,没有考虑太多。如今不仅要确保能切过去,并且还需要切过去运行一天甚至是一周的时间,对于切换时间同样也有很高的要求。
虽然 DataGuard 是非常成熟的容灾技术,但是受各种运行环境的影响,仍然可能在切换过程中出现各种意外,导致切换时间超时。今天我们就来梳理一下切换过程中的各种坑,帮你理清楚整个的切换流程。
切换过程梳理
首先我们简单列举出常规的灾备切换流程,便于更好的理解整个过程。
1.停止业务系统的运行
2.完成数据库主备切换
3.修改数据库DNS解析 (或者应用修改连接串)
4.启动业务系统,确认连接到新主库
上述的步骤中,1/3/4主要是网络和业务系统的调整,不在这次讨论的范围。今天我们重点要讨论的是第二步。
接着,我们从数据库内部对主备切换过程进行一个细粒度的分解。
12c之前的切换过程是这样的,
a. 主库发出切换备库的命令后,发起一次日志切换(,这个日志中会包含日志结束的标记),如果命令中带有with session shutdown,还会杀掉数据库中的活动会话
b. 备库接收到归档日志后进行Media Recovery,应用到日志结束标记后,完成日志同步
c. 主库接收到备库完成日志应用后,将控制文件中的角色修改为Standby Database,然后以abort的方式关闭主库
d. 备库上发起切换主库的命令,关闭MRP进程,清理在线日志文件,将控制文件中的角色修改为Primary Database
e. 新的主库上执行open命令,打开数据库对外提供服务
f. 后续再启动新的备库,开启MRP日志应用 (这个时候已经不影响业务系统的使用)
在这个过程中,容易出意外的 a 和 e 两步,一个是原主库的关闭,一个是新主库的启动。
影响原主库关闭速度的原因
影响原主库关闭速度主要有两个原因,
1.带业务切换的场景中,数据库中有大量的会话, 关闭数据库时需要杀掉这些会话,这个过程消耗了很多的时间。
为了规避这个问题,我们可以先关闭或者部分关闭应用;
2.关闭过程中遇到Bug
在12c的环境下进行 DG 切换时,可能会遇到 SCM0 进程长时间无法关闭的问题,解决方法是禁用 DLM 统计信息收集。
Active process 8968 user 'oracle' program 'oracle@db24pr02 (SCM0)', not in a wait
Active process 8968 user 'oracle' program 'oracle@db24pr02 (SCM0)', not in a wait
alter system set "_dlm_stats_collect" = 0 scope = spfile sid = '*’;
SCM0 (Slave DLM(Distributed Lock Management) Statistics Collection and Management)后台进程负责收集和管理全局入队服务(GES)和全局缓存服务(GCS)的统计信息;只有在数据库中启用了DLM统计信息收集 SCM0 才会存在, 根据官方文档描述,在12.2版本中即使收集了 DLM 统计信息,use these stats service based affinity and cache warmup功能也是禁用的,只是为了后续版本准备,所以在禁用该进程不会对12CR2版本产生负面影响。
影响新主库open速度的原因
不论备库是 mount 状态还是 open read only 状态,切换成主库角色后,都会变成 mount 状态,需要执行 open 命令打开。
在 12C 的环境下打开主库时,可能会遇到长时间等待 "clear SRLs" 的问题,导致主库迟迟不能正常对外提供服务。
Sleep 80 seconds and then try to clear SRLs in 17 time(s)
......
Successfully onlined Undo Tablespace 2.
Undo initialization finished serial:0 start:363400623 end:363952914 diff:552291 ms (552.3 seconds)
这个问题是因为触发Bug 23263748,因此建议在 12C 的环境中打上这个补丁。
关于切换流程的优化
12C 之前的切换步骤是这样的,
## 主库切换成备库
alter database commit to switchover to physical standby with session shutdown;
## 备库切换成主库
alter database commit to switchover to primary;
alter database open;
核心的步骤其实就两条,但这里存在几个问题:
1.对于能够正常切换成功,没有明确的判断条件。官方提供了 v$database.switchover_status字段,分别用Allow、NotAllow和SessionActive来表示允许或者不允许切换,以及是否还有活动会话存在。但即使是Allow状态,也仍然存在很多切换失败的案例;
2.切换命令需要分别连接到主备库执行,这也造成了一些不便,尤其是现在很多客户都用自动化切换,会多出一次主机登录的动作;
3.主库执行切备库的命令后,什么时候执行备切主的命令,需要自行判断。尤其是自动化场景中,也会造成一定的麻烦。
所以12c之后对DG切换进行了增强,增加一个verify命令,验证成功则说明具备主备切换条件,验证失败则需要进一步分析失败的原因。正式切换的命令也只有一条,在主库上执行这条命令后,会自动完成一系列的切换动作,不需要过多的干预。
## 校验ADG切换
alter database switchover to coredg verify;
## 正式切换
alter database switchover to coredg;
关于异常切换
以上我们所讨论的都是正常的例行切换,灾备库还有一个更重要的功能就是为了应对异常情况或者极端场景,比如主库数据库损坏或者主生产中心地震、火灾等,这时候需要在没有主库的情况下拉起备库,继续对外提供服务。在这些场景下会面临数据丢失的风险。
为了说清楚这个问题,我们简单介绍一下 DG 支持的三种保护模式。
虽然提供了3种保护模式,但绝大多数环境中为了不影响主库的可用性和性能,DG 库均配置为最大性能模式,存在着理论上丢失数据的可能。因此一旦涉及到有损切换,就不得不掂量下到底会丢多少数据。尤其是像金融行业,对于 RTO 和 RPO 都有着严格的要求,核心系统的 RPO 要求甚至是 0 。
为了满足业务系统 RPO 的要求,同时又尽量减少对性能的影响,12C 引入了一个新的组件 Far Sync。相比于普通的 DG 库,Far Sync 实例有两个特点:
1.只有实例和控制文件,没有数据文件,节省了保存数据文件所需要的存储开销;
2.轻量级的架构,可以将 Far Sync 实例部署在生产本地机房,配置为实时同步模式接收主库的归档日志文件,异步分发到远程灾备节点。
部署了 Far Sync 的灾备环境中,最大的好处是可以进行无损的 Failover 切换。因为主库的日志是实时同步到 Far Sync 实例的,所以在做 Failover 的时候并没有数据损失,只是 RTO 的时间会增加一些。在一个正常传输的网络环境中,这点时间几乎可以忽略不计。
总结
这篇文档中主要介绍了 DG 切换过程中可能遭遇的问题,影响 DG 切换时效;也对比了 12C 版本前后切换过程的差异,总体的趋势是切换过程更加简便和智能,不少的客户已经能够在1分钟内完成例行的主备切换,对于强一致性要求的 Oracle 数据库,能做到这个水平,已经是非常的难能可贵;对于灾难切换,给大家介绍了新的 Far Sync 架构,能够在对数据库性能影响最小的情况下,做到数据零丢失,对于 RPO 要求为零的业务,是一个不错选择。
最后,大家在容灾切换过程中遇到哪些坑,也欢迎留言一起讨论。