1 正常运行状态
守护系统正常运行时,同一个守护进程组中,只有一个主库,其他的都是备库。
主库处于 Open 状态,主库守护进程也处于 Open 状态,守护进程控制文件是 Valid有效状态。
所有备库也处于 Open 状态,所有备库守护进程处于 Open 状态,守护进程控制文件是Valid 有效状态。
主库到所有备库的归档也都处于 Valid 有效状态。
MPP 主备系统中,所有主库的 dmmpp.ctl 都处于一致状态。
#查看归档:
SQL> select * from v$arch_status;
LINEID ARCH_TYPE ARCH_DEST ARCH_STATUS
---------- --------- ----------- -----------
1 TIMELY GRP2_RWW_01 VALID
2 TIMELY GRP2_RWW_02 VALID
3 TIMELY GRP2_RWW_03 VALID
4 LOCAL /dm/dmarch VALID
used time: 2.229(ms). Execute id is 5.
SQL>
#守护进程:
SQL> select group_name,inst_name,dw_type,dw_mode,auto_restart,dw_status from v$dmwatcher;
LINEID GROUP_NAME INST_NAME DW_TYPE DW_MODE AUTO_RESTART DW_STATUS
---------- ---------- ----------- ------- ------- ------------ ---------
1 GRP2 GRP2_RWW_01 GLOBAL AUTO 1 OPEN
used time: 1.498(ms). Execute id is 59.
SQL>
2 数据守护的启动
Normal 模式的库默认以 Open 状态启动,也可以通过增加启动参数 Mount,将数据库启动到 Mount 状态。而 Primary/Standby 模式的库启动后,自动进入 Mount 状态,因此,数据守护系统启动时,所有数据库实例处于 Mount 状态。所有守护进程处于 Startup状态。如果实例还未启动到 Mount 状态(比如还处于 After redo 状态),守护进程不会通知实例 Open。
1)Local 守护类型的守护进程,直接 Open 数据库实例,并修改守护进程状态为 Open。
2)Global 守护类型的守护进程,需要相互协调信息,自动将数据库实例切换到 Open 状态,并将守护进程状态也切换为 Open。
Global守护类型的守护进程将 Standby模式数据库实例切换为Open状态的条件是:
1)守护进程控制文件有效,并且没有被标记为分裂或无效状态。
2)检测到活动主库(主库为 Open 或 Mount 状态),并且主备库数据保持一致(根据LSN 判断)、或者是活动主库的可恢复备库。
3)守护进程 Open 数据库实例后,再将自己切换为 Open 状态。
因此,在检测到活动主库之前,备库一直保持 Mount 状态,守护进程保持 startup状态,分裂备库也会一直保持 mount 状态。
Global守护类型的守护进程将 Primary模式数据库实例切换为Open状态的条件是:
1)守护进程控制文件有效,并且没有被标记为分裂或无效状态。
2)在守护进程组内,当前归档状态有效的实例和对应的守护进程都处于活动状态。
3)在守护进程组内,当前已经收到的守护进程消息中,守护进程和实例状态正常(不是 Error 状态),并且远程守护进程不是 Takeover 或 Switchover 状态。
4)根据数据库模式、LSN 信息判断,监控的数据库不是其他数据库的可恢复备库。
如果通过监视器没有观察到实例 Open,可以借助监视器的 Check Open 命令查找原因,可以根据命令返回的原因考虑是否进行人工干预,比如需要通过监视器命令强制 Open 实例。
手动方式启动数据守护系统时,对于守护进程,数据库实例和监视器的启动顺序没有严格要求,也可以通过监视器命令启动守护系统(前提是所有守护进程已经启动)。 启动流程中,会设置主库实时归档/即时归档为 Invalid 状态。Primary模式数据库实例切换为 Open 状态时,需要回滚活动事务、Purge 已提交事务,并重构回滚段,会引发数据变化,LSN 增长,因此数据守护启动完成后,
主备库数据肯定是处于不一致状态。
主库守护进程 Open 主库后,会修改 INST_RECOVER_TIME 内存值为 0(默认 60 秒),确保备库 Open 后,马上启动故障恢复流程,同步主库数据完成后,重新将归档设置为 Valid 状态。
如果在故障恢复流程完成之前,主库故障,将无法执行备库接管;备库强制接管会引发守护进程组分裂。
读写分离集群,在 Timely 归档变为 Valid 之前,不会在备库上创建数据库连接,只读操作也无法分流到对应的备库。
3 强制 Open 实例
正常情况下,守护进程 dmwatcher 可以自动 Open 数据库实例,但某些情况下(比如备库硬件故障无法启动),数据守护系统不满足启动条件,我们可以通过监视器执行 Open instance 命令,强制 Open 数据库实例。主备库都可以强制 Open,其执行流程如下:
假设需要强制 Open 数据库 A,只需要启动一个监视器,登录后输入 Open instance A 即可完成强制启动。
如果实例 A 是 Standby 模式,强制 Open 的执行流程如下:
- 通知 A 的守护进程切换为 Open Force 状态
- 通知实例执行 Open 操作
- 通知守护进程切换 Open 状态
如果实例 A 是 Primary 模式,强制 Open 的执行流程如下:
- 通知 A 的守护进程切换为 Open Force 状态
- 修改 A 到所有归档目标的实时归档/即时归档状态为无效
- 修改守护进程控制文件,增加实例 A 强制 Open 记录项
- 通知实例执行 Open 操作
- 通知守护进程切换 Open 状态
Primary 模式数据库实例切换为Open状态时,需要回滚活动事务、Purge已提交事务,并重构回滚段,会引发数据变化,LSN 增长。因此,强制Open主库后,需要在守护进程控制文件中增加强制Open项。并且,这个操作可能会引发守护进程组分裂,比如:
- 主库 A 故障
- 备库 B 接管,成为主库
- B 故障
- A 重启,并强制 Open
- A 和 B 数据不一致,并且无法恢复到一致状态。此时,B 重启,就会产生守护进程组分裂。
强制 Open 主库前,会设置主库到所有归档目标的实时归档/即时归档为Invalid 状态。
强制 Open 主库命令,会修改主库守护进程 INST_RECOVER_TIME 内存值为0(默认 60 秒),确保备库 Open 后,马上启动故障恢复流程,同步主库数据完成后,重新将归档设置为 Valid 状态。
如果在故障恢复流程完成之前,主库故障,将无法执行备库接管;备库强制接管会引发守护进程组分裂。
4 关闭数据守护系统
退出守护系统时,必须按照一定的顺序来关闭守护进程和实例。特别是自动切换模式,如果退出守护进程或主备库的顺序不正确,可能会引起主备切换,甚至造成守护进程组分裂。
通过监视器执行 Stop Instance 命令关闭数据守护系统,是最简单、安全的方式。
命令执行成功后,数据库实例正常关闭。但守护进程并没有真正退出,而是将状态切换为Shutdown 状态。
Stop Instance 命令内部流程如下:
1) 通知守护进程切换为 Shutdown 状态
2) 通知主库退出
3) 通知其他备库退出
如果使用手动方式关闭数据守护系统,请严格按照以下顺序:
1) 如果启动了确认监视器,先关闭确认监视器(防止自动接管)
2) 关闭备库守护进程(防止重启实例)
3) 关闭主库守护进程(防止重启实例)
4) Shutdown 主库
5) Shutdown 备库
先关闭主库再关闭备库,顺序一定不能错。对于本地守护类型的实例,在关闭数据守护系统时,不受此顺序限制。
因为主库 Shutdown 过程中,需要 Purge 所有已提交事务,会修改数据,并产生 Redo 日志。如果先 Shutdown 备库,会导致主库发送归档日志失败,并且由于主库已经处于 Shutdown 状态,会导致主库异常关闭。