在数据库高可用架构中,脑裂(Split-Brain) 是最令人头疼的问题之一——同一个集群中出现两个活动主库,各自接收写入请求,数据一致性瞬间崩塌。
达梦DM8数据守护(Data Watch)集群通过一套精密的自动切换机制来应对主库故障,同时设计了多重防脑裂保护。而在这些保护机制中,DW_FAILOVER_FORCE这个参数扮演着关键却又容易被忽视的角色。
本文将从实际案例出发,学习达梦数据守护集群的自动切换原理,并重点解读DW_FAILOVER_FORCE的作用机制。
理解自动切换之前,先明确几个核心角色:
组件 作用
主库(Primary) 承担读写业务,产生Redo日志
备库(Standby) 接收并重演Redo日志,保持数据同步
守护进程(dmwatcher) 监控数据库状态,处理故障切换,是集群的"神经中枢"
监视器(dmmonitor) 提供全局集群视图,执行管理命令,支持自动/手动切换
数据守护的核心原理非常简洁:主库将产生的Redo日志传输到备库,备库接收并重演这些日志,从而实现数据同步。
达梦数据守护支持两种故障切换模式:
手动切换(MANUAL):主库故障后,需要人工通过监视器执行接管命令
自动切换(AUTO):系统自动将备库切换为主库,前提是必须部署确认监视器(Confirm Monitor)
自动切换模式下,确认监视器扮演着"裁判"的角色——它负责检测主库故障、选出最优备库、并通知备库执行接管。
确认监视器在以下三种场景下会启动自动接管流程:
主库数据库实例异常终止,主库守护进程正常
主库硬件故障,或者数据库实例和守护进程同时故障
主库网络故障,主备库之间、主库与监视器之间连接异常
以一个典型场景为例:某生产环境主库CZFX01因网络波动与备库、监视器通信中断,集群发生分裂
整个自动切换过程如下:
主库因网络波动无法向备库发送归档日志,自动切换为Suspend(挂起)状态,限制Redo日志写入,防止主库继续产生新日志导致数据分歧。
此集群DW_FAILOVER_FORCE参数为1,当主库守护进程在三倍的DW_ERROR_TIME(默认15秒)内未收到备库和监视器的确认消息,若满足Failover条件,守护进程会切换至Failover状态。
当备库与监视器网络恢复稳定,满足接管条件时,确认监视器发起Takeover指令,通知备库执行接管。
备库收到指令后,应用KEEP_RLOG_PKG(缓存的日志包),切换为Primary模式并Open,成为新主库对外提供服务。
原主库网络恢复后,通过OHIS信息比对发现本地LSN大于备库,判断存在分裂,执行Shutdown强制关闭。
在实时归档(REALTIME)模式下,达梦引入了一个巧妙的设计——KEEP_RLOG_PKG(保留日志包)。
主库在将日志包写入本地联机日志之前,先发送到备库。备库收到后并不立即重演,而是将其标记为KEEP_RLOG_PKG暂存在内存中【参考文档-DM8数据守护手册】。
为什么这样做?考虑一个危险场景:
KEEP_RLOG_PKG机制完美规避了这个问题——备库暂不重演,等确认主库已成功落盘后才开始重演。这为实现事务一致性模式奠定了基础。
DW_FAILOVER_FORCE是dmwatcher.ini中的一个配置参数【参考文档-DM8数据守护手册】:
取值 含义
0 在确认监视器未响应时,不允许主库强制Open,主库一直保持Suspend挂起状态
1 在确认监视器未响应时,主库守护进程经过3倍DW_ERROR_TIME确认时长后,若满足条件则强制将主库重新Open
故障自动切换模式下,确认监视器必须一直处于启动状态【参考文档-DM8数据守护手册】。但在实际生产环境中,可能出现以下情况:
在这些情况下,主库守护进程无法通过确认监视器来确认备库状态,会一直处于Confirm确认状态,主库实例则处于Suspend挂起状态【参考文档-DM8数据守护手册】。
如果没有DW_FAILOVER_FORCE参数,主库将永远挂起,业务完全中断。
当参数配置为1时,即使没有确认监视器,主库守护进程在满足以下所有条件后,允许切换至Failover状态执行故障处理【参考文档-DM8数据守护手册】:
主库守护进程经过3倍DW_ERROR_TIME 的确认时长后,若认定自己仍然满足重新Open条件,则将主库重新Open,后续进行正常的备库恢复处理【参考文档-DM8数据守护手册】。
达梦将DW_FAILOVER_FORCE默认设置为1,体现了"可用性优先" 的设计哲学:
在无法确认备库状态的情况下,与其让主库无限期挂起,不如冒险恢复主库服务
即使后续发现数据不一致,也可以通过重建备库等方式恢复
对于大多数生产环境,服务可用性比绝对数据一致性的优先级更高(当然,这取决于具体的业务场景)
ps:需要特别说明的是,该参数在8.1.5.71后默认值修改成了0。
将DW_FAILOVER_FORCE设置为0的场景包括:
达梦数据守护系统为预防脑裂做了大量工作:
强制配置确认监视器:自动切换模式下必须部署确认监视器,启动故障切换前进行严格条件检查
限制手工干预:设置ALTER_MODE_STATUS=0,禁止用户直接通过SQL修改数据库模式、状态和OGUID
守护进程自动检测:一旦检测到脑裂发生,马上强制退出所有活动主库
守护进程通过比较本地和远程库的Open记录(SYSOPENHISTORY) 来判断是否发生分裂:
如果两个库的Open记录相等:选出一个作为主库
如果Open记录存在包含关系:被包含的库作为备库重加入
如果Open记录既不相等也无包含关系:发生分裂,守护进程设置分裂状态并强制关闭被分裂的库
回到开篇的案例,网络波动导致通信中断,主库进入Suspend状态。但值得庆幸的是:
通过分析sql日志查看双主期间的请求情况可以看到,这期间实际并无实际写入(唯一一条update由于通信异常执行失败了)
这也说明:脑裂的真正危害不在于出现两个主库本身,而在于两个主库同时接收写入。如果能在脑裂期间阻止写入,数据就是安全的。
同时,在实际生产过程中发现脑裂时,可以优先检查sql日志确认双主期间的业务请求。
基于以上分析,给出以下配置建议:
场景 DW_FAILOVER_FORCE 理由
核心交易系统(强一致性) 0 宁可暂停服务,也不允许数据异常
一般业务系统 1 优先保障服务可用性
网络不稳定环境 0 避免频繁误判触发自动Open
有异地灾备 0 可以从灾备端接管
检查集群节点间及与监视器之间的网络链路,避免单点故障;考虑部署冗余网络或使用Bonding提高稳定性。
达梦数据守护集群的自动切换机制,是一套从日志同步、故障检测、状态确认到自动接管的完整闭环。而DW_FAILOVER_FORCE参数,则是这套机制中平衡可用性与一致性的关键调节阀:
DW_FAILOVER_FORCE=1:在确认监视器不可达时,主库经过超时等待后强制Open,优先保障服务可用性
DW_FAILOVER_FORCE=0:主库永久挂起,等待人工介入,优先保障数据一致性
没有绝对正确的配置,只有最适合业务场景的选择。理解这个参数背后的设计哲学,才能在关键时刻做出正确的决策。
文章
阅读量
获赞
