| 机器名 | IP 地址 | 状态 |
|---|---|---|
| dw1 | 192.168.43.11 192.168.233.11 | 主库 GRP1_RT_01 |
| dw2 | 192.168.43.12 192.168.233.12 | 备库 GRP1_RT_02 |
| dwm | 192.168.233.13 | 确认监视器 |
| 守护 WSTATUS 状态 | 核心含义 |
|---|---|
| Startup | 守护进程启动状态,需要根据远程守护进程发送的状态信息,结合本地数据库的初始模式、状态和数据同步情况,确定本地数据库的启动模式和状态后,进入 Open 状态。 |
| Open | 守护进程正常工作,监控数据库,并定时发送数据库的状态信息,接收其他守护进程发送的信息,接收监视器发送的用户请求。 |
| Confirm | 通过监视器确认远程主(备)库是否活动的过程中,守护进程设置为 Confirm 状态。 |
| Failover | 监视器确认备库故障,开始执行故障处理,解除归档依赖,恢复主库业务 |
| Takeover | 主库宕机,备库执行接管,升级为主库 |
| Switchover | 计划内手动主备互换,无故障 |
| Recovery | 备库追赶主库缺失 redo 日志,数据同步阶段 |
| Error | **** 超过一段时间(DW_ERROR_TIME)没有接收到远程守护进程消息,本地守护进程或监视器认定远程守护进程故障,修改远程守护进程为 Error 状态。 |
| ISTATUS 实例状态 | 含义 | 实验场景 & 现象 |
|---|---|---|
| STARTUP | 实例刚启动,正在加载控制文件、打开数据文件,启动初始化阶段。内部自动状态,无法手动设置。 | 前台启动./dmserver dm.ini mount,刚拉起 dmserver 瞬间短暂处于 Startup;还没做完 redo 重做。 |
| AFTER REDO | 联机日志 REDO 重做完成,活动事务还没回滚,在 OPEN 之前的内部过渡状态。内部自动状态,不能手动改。 | 实例启动,redo 回放完毕,准备进入 MOUNT 或 OPEN;备库 Recovery 日志追赶过程也会短暂经过这个状态。 |
| MOUNT | 挂载状态。不能访问业务表、不能查询数据;仅允许控制文件、归档、数据库模式修改操作(切换 PRIMARY/STANDBY 就在 MOUNT 阶段)。 | 1. 手动前台启动:./dmserver dm.ini mount2. Switchover/Takeover 接管流程中,实例先切 MOUNT,修改 IMODE,再 OPEN。备库正常运行不是 MOUNT,备库正常是 OPEN。 |
| OPEN | 正常打开状态。对外提供数据库访问;主库可读写,备库仅可读(STANDBY)。集群健康时主备 ISTATUS 都是 OPEN。 | 集群正常稳态;主库 PRIMARY+OPEN;备库 STANDBY+OPEN。 |
| SUSPEND | 挂起状态。SELECT 读可以执行;一旦触发 REDO 刷盘(INSERT/UPDATE/DELETE/COMMIT),会话阻塞挂起。 | 【重点实验状态】AUTO 实时归档,备库不可达 / MAL 断网,主库进入 SUSPEND,业务写操作卡住;守护进程 WSTATUS 变为 Confirm,等待监视器确认。Failover 流程成功后,实例从 SUSPEND 恢复 OPEN。 |
| SHUTDOWN | 实例关闭,dmserver 进程退出。 | kill -9 dmserver、正常 shutdown 数据库后,ISTATUS=SHUTDOWN;监视器里 INST_OK=Error。 |
当出现硬件故障(掉电、存储损坏等)原因导致主库无法启动,或者是主库内部网卡故障导致主库短期不能恢复正常的情况下,可使用备库接管功能,将备库切换为主库继续对外服务。
主库故障时,备库接管进行接管,需要满足以下条件,防止集群出现分裂
1.主库是primary,open状态时,发生故障。
2.执行Takeover时,允许主库守护进程故障,但是要求故障前是 Open/Recovery 状态。或主库守护进程非ERROR状态。
3.主库故障前到接管备库的归档状态为 Valid。
4.接管备库必须为standby,open状态。
5.接管备库守护进程为open/Startup 状态
6.接管备库的守护进程控制文件状态为Valid
7.故障主库和接管备库的 Open 记录项内容相同
将主库服务器关闭,模拟故障,处理流程如下
[monitor] 2026-09-24 11:41:06.810: 检测到PRIMARY实例故障,开始对组(GRP1)执行自动接管
[monitor] 2026-09-24 11:41:06.812: 通知组(GRP1)当前活动的守护进程设置MID
[monitor] 2026-09-24 11:41:06.865: 通知组(GRP1)当前活动的守护进程设置MID成功
[monitor] 2026-09-24 11:41:06.866: 开始使用实例GRP1_RT_02接管
[monitor] 2026-09-24 11:41:06.867: 通知守护进程GRP1_RT_02切换TAKEOVER状态
[monitor] 2026-09-24 11:41:06.870: 守护进程(GRP1_RT_02)状态切换 [OPEN-->TAKEOVER]
[monitor] 2026-09-24 11:41:06.919: 切换守护进程GRP1_RT_02为TAKEOVER状态成功
[monitor] 2026-09-24 11:41:06.920: 实例GRP1_RT_02开始执行SP_SET_GLOBAL_DW_STATUS(0, 7)语句
[monitor] 2026-09-24 11:41:06.972: 实例GRP1_RT_02执行SP_SET_GLOBAL_DW_STATUS(0, 7)语句成功
[monitor] 2026-09-24 11:41:06.973: 实例GRP1_RT_02开始执行SP_APPLY_KEEP_PKG()语句
[monitor] 2026-09-24 11:41:07.025: 实例GRP1_RT_02执行SP_APPLY_KEEP_PKG()语句成功
[monitor] 2026-09-24 11:41:07.026: 实例GRP1_RT_02开始执行ALTER DATABASE MOUNT语句
[monitor] 2026-09-24 11:41:07.079: 实例GRP1_RT_02执行ALTER DATABASE MOUNT语句成功
[monitor] 2026-09-24 11:41:07.080: 实例GRP1_RT_02开始执行ALTER DATABASE PRIMARY语句
[monitor] 2026-09-24 11:41:07.181: 实例GRP1_RT_02执行ALTER DATABASE PRIMARY语句成功
[monitor] 2026-09-24 11:41:07.183: 通知实例GRP1_RT_02修改所有归档状态无效
[monitor] 2026-09-24 11:41:07.234: 修改所有实例归档为无效状态成功
[monitor] 2026-09-24 11:41:07.235: 实例GRP1_RT_02开始执行ALTER DATABASE OPEN FORCE语句
[monitor] 2026-09-24 11:41:07.387: 实例GRP1_RT_02执行ALTER DATABASE OPEN FORCE语句成功
[monitor] 2026-09-24 11:41:07.388: 实例GRP1_RT_02开始执行SP_SET_GLOBAL_DW_STATUS(7, 0)语句
[monitor] 2026-09-24 11:41:07.440: 实例GRP1_RT_02执行SP_SET_GLOBAL_DW_STATUS(7, 0)语句成功
[monitor] 2026-09-24 11:41:07.441: 通知守护进程GRP1_RT_02切换OPEN状态
[monitor] 2026-09-24 11:41:07.444: 守护进程(GRP1_RT_02)状态切换 [TAKEOVER-->OPEN]
[monitor] 2026-09-24 11:41:07.493: 切换守护进程GRP1_RT_02为OPEN状态成功
[monitor] 2026-09-24 11:41:07.494: 通知组(GRP1)的守护进程执行清理操作
[monitor] 2026-09-24 11:41:07.548: 清理守护进程(GRP1_RT_02)请求成功
[monitor] 2026-09-24 11:41:07.550: 使用实例GRP1_RT_02接管成功
备库GPR1_RT_02实例日志
备库守护进程会将主库GRP1_RT_01守护进程状态判断为error,归档状态为invalid,
在收到监视器命令后,开始主库接管
GRP1_TR_02成为新的主库
-- 02继续提供服务,向02写入数据
SQL> insert into test values(3);
SQL> commit;
主库故障后立即重启,此时主库的守护进程变成 Startup 状态,重新进入守护进程的启动流程,将数据一致的备库归档设置为有效状态,其余备库归档设置成无效状态,并重新 Open 主库。Open 成功后继续作为主库,当检测到归档状态无效的备库正常时会启动 Recovery 处理流程,重新同步主备库数据。
启动GRP1_TR_01服务器,开始故障恢复
GRP1_TR_01故障恢复后,会有监视器下达命令,从原本的主库角色变为备库,加入GRP1_RT_02
恢复相关流程如下:
GRP1_RT_01查询刚刚更新的数据,数据已经同步
备库产生故障(硬件故障或者内部网卡故障)时,主库的处理流程对手动切换、自动切换模式处理上有些差异。
当前集群状态
GRP1_RT_02 为primary,open
GRP1_RT_01 为standby,open
对于手动切换模式,检测到备库故障后,主库会直接将备库归档失效,不会切换到 suspend 状态,守护进程也不会切 Failover 状态。
对于自动切换模式,主库的守护进程会自动判断切换到 Failover 状态或者 Confirm 确认状态,如果两种状态切换条件都不满足,则保持当前状态不变。
(1)自动切换模式下,主库守护进程不进入 Confirm 确认状态,直接切换到 Failover 条件:
1.备库实例故障,或主备之间网络故障,或备库重演时校验LSN不匹配,这些会导致主库同步日志到备库失败,使主库处于suspend状态。
2.主库到此备库的归档状态是Valid
3.主库守护进程处于startup,open或Recovery状态
4.当前没有监视器命令正在执行
5.备库实例故障,备库守护进程正常
模拟备库实例故障,守护进程正常
-- kill GRP1_RT_01(备库),为防止守护进程拉起,暂时移走dm.ini
主库守护进程进入 Failover 状态后的执行流程(自动或手动切换模式下执行流程相同):
通知主库修改发送归档失败的备库归档状态无效
通知主库重新 Open。
将主库的守护进程切换为 Open 状态
此时主库守护进程会之间进入Failover,进行故障处理,如下图
备库恢复
(2)备库实例和守护故障,但主库与监视器通信正常
关闭备库服务器
主库的守护进程收到了确认监视器返回的确认消息,如果确认监视器认定可以执行 Failover,则主库的守护进程会切换为 Failover 状态并执行对应的处理;如果确认监视器认定不满足执行 Failover 条件,则主库的守护进程会一直保持在 Confirm 状态。确认监视器认定主库可以执行 Failover 条件:
1.主库守护进程处于confirm状态
2.主库实例正常,处于Suspend
3.主备没有被接管,不存在其他主库
4.没有 takeover/switchover 命令在执行
5.当前所有归档有效的备库均可以加入主库
此时主库守护进程会先进行一直尝试与备库守护进程确认备库示例状态,但备库的守护进程故障,在DW_ERROR_TIME时间后,进入Failover状态,进行故障处理,如图
我们从主库守护进程日志也可以看到这样的变化
备库恢复
主库GRP1_RT_02准备发送归档
主库GRP1_RT_02发送归档成功,切换为suspend,继续发送归档
GRP1_RT_02归档全部发送完后,等待GRP1_RT_01归档有效后,切换为open状态
(3)备库实例和守护故障,且主库与监视器通信异常
主库和确认监视器之间网络连接异常,或者没有启动确认监视器。满足下面条件后主库允许切换至 Failover 状态执行故障处理:
1.主库实例正常,处于 Suspend 状态
2.备库守护进程正常
3.主库没有被接管,不存在其他主库
4.没有 takeover/switchover 命令正在执行
5.备库故障前可以加入主库
首先停止监视器服务,接着关闭GRP1_RT_01服务器
故障处理
此时由于备库实例和守护进程故障,主库与监视器也无法通信,主库的守护进程会直接进入Failover 状态执行故障处理。
将GRP1_RT_01守护进程状态设置为error
恢复流程
此时并没有开启监视器服务,但依然可以同步归档日志(备库故障),恢复集群
主库更新数据
备库同步正常
主库公共网络故障,主备库正常、内部网络正常情况下,用户无法远程连接主库执行正常的数据库操作。这种情况下,用户可以通过 Switchover 命令,将备库切换为主库,确保数据库服务不受影响。
-- 禁用主库GRP1_RT_02外网网卡,此时主库的远程连接都会断开,只有备库可连接,不可做修改操作。
ip link set ens33 down
-- 主库外网故障,监视器不会做出响应,需要用户手动切换主备库。
登录监视器
switchover GRP1_RT_01
连接新的主库GRP1_RT_01,现在远程连接恢复了修改操作
主库修改数据
在备库服务器本地登录(外网网卡已禁用),数据依然同步
DM 数据守护对内部网络的可靠性提出了很高的要求,但是在实际应用中(比如异地容灾),存在很多不可控因素,内部网络无法保证绝对可靠。守护进程和守护进程之间、守护进程和监视器之间通过超时机制来检测是否出现故障,当内部网络出现故障时,超过设置时间未收到远程消息,会认定远程故障。
下面的表格说明在外部网络正常时,内部网络故障的场景以及守护进程的处理策略:
| 故障类型 | 手动切换处理策略 | 自动切换处理策略 |
|---|---|---|
| 主库内部网卡故障 | 主库不会挂起、不会走 failover 流程,归档设置无效,异步工作 | 归档失败时,主库挂起,主库守护进程保持 Confirm 状态,确认监视器自动寻找备库自动接管。因为外网还是正常的,在经过 SESS_FREE_IN_SUSPEND 参数配置的时间后,老主库会自动断开所有连接,以便应用连接能够转移到新接管的主库上,详见下文说明。 注:此场景下主备库之间无法通信,但确认监视器仍然可以和备库的守护进程正常通信 |
| 备库内部网卡故障 | 主库不会挂起、不会走 failover 流程,归档设置无效,异步工作 | 归档失败时,主库挂起,主库守护进程 Failover(经过 Confirm 状态确认后 Failover),归档设置无效,异步工作。 注:此场景下主备库之间无法通信,但确认监视器仍然可以和主库的守护进程正常通信 |
集群当前状态
GRP1_RT_01:primary、open
GRP1_RT_02:standby,open
主库不会挂起、不会走 failover 流程,归档设置无效,异步工作
归档失败时,主库挂起,主库守护进程保持 Confirm 状态,确认监视器自动寻找备库自动接管。 因为外网还是正常的,在经过 SESS_FREE_IN_SUSPEND 参数(dm.ini参数)配置的时间后,老主库会自动断开所有连接,以便应用连接能够转移到新接管的主库上。
-- 禁用主库内网网卡
ip link set ens37 down
监视器处理流程
主库内网网卡故障,监视器接收不到主库守护进程消息,会判断为主库故障,从备库中选取接管角色,流程同 --主库故障、备库接管-- 一节一样
主库守护进程日志
主库守护收到集群消息:GRP1_RT_02 正在执行Takeover 接管流程,为防止双主(split 脑裂),执行ACT_SHTDWN:关闭本地旧主库实例
主库守护进程向本地 dmserver下发,SHUTDOWN ABORT命令,
主库实例断开和 dmwatcher 之间的本地 连接,TCPMAL_INST_DW_PORT关闭
主库守护检测实例消失,自动重启本地实例
主库实例日志
主库内网网卡故障,MAL 的 recv 系统调用失败,收到`errno=104`,TCP 连接被重置,主备实例的MAL连接丢失,后续自动尝试新建控制通道
此时收到守护进程命令,执行SHUTDOWN ABORT,实例立刻异常终止
实例被守护进程拉起,数据库内核重新初始化
重启后 MAL 持续告警,由于dmmal.ini里写死的 MAL_HOST=`192.168.233.11`,但是当前服务器本机网卡 IP被禁止,MAL 在尝试建立到备库 site (1) 的连接时,校验本地 IP 不匹配,直接创建 MAL 控制链路失败
启动GRP1_RT_01内网网卡
ip link set ens37 up
因为目前已有主库GRP1_RT_02,因此监视器会把GRP1_RT_01修改为备库
实例日志
网卡恢复后,执行 `ALTER DATABASE OPEN FORCE` 打开数据库
数据库 OPEN 后,开始生成归档日志文件
收到集群节点 GRP1_RT_02 发来 MAL 指令,**DW 状态从恢复态 DW_RECOVERY 切为 NONE**,代表集群恢复完成
主库不会挂起、不会走 failover 流程,归档设置无效,异步工作
归档失败时,主库挂起,主库守护进程 Failover(经过 Confirm 状态确认后 Failover),归档设置无效,异步工作。
当前状态
GRP1_RT_01为备库,停止GRP1_RT_01网卡
主库实例日志
主库 MAL 线程检测到到备库的 MAL 通道断开
后续不断尝试重建 socket,但主库实例不会因为备库 MAL 断连而宕机
监视器也只是确认GRP1_RT_01守护进程消息超时,无后续操作
此时主备环境处于异步工作,二者都可访问,但备库无法进行数据修改。
备库内网网卡未恢复前,对主库数据进行修改
此时查询备库,新的数据未同步
恢复备库内网网卡
ip link set ens37 up
-- 再次查询,数据已同步
监视器日志
从监视器来看,收到备库守护进程消息后,主库GRP1_RT_02守护进行会进入failover状态,流程同备库故障处理一样。
文章
阅读量
获赞
