在分布式数据库架构下,当数据库节点异常时,数据库管理组件能够自动感知到异常并触发节点隔离或者自动切换,是数据库高可用容灾的基本能力。在节点服务器异常、网络异常或进程异常等场景下,各数据库产品本身已经具备了可靠的检测能力和恢复手段。但是在服务器磁盘异常或者IO缓慢等场景下,数据库本身对这类故障场景的检测能力如何,能否采取及时的故障恢复措施,本文将结合几种常见的国产分布式数据库进行分析。
1、OceanBase数据库
OceanBase数据库整体架构如图所示,一个集群由若干节点组成,这些节点组成不同的可用区Zone。可用区是逻辑概念,具有IDC和Region属性。OB数据库中表数据按照不同的规则划分为不同分片,每个分片称为分区Partition,分区又运行在不同的节点OBServer上。
在OceanBase数据库中分为系统租户和业务租户,其中系统租户中的Root Service承担了OceanBase数据库的大量管理工作,包括集群管理,租户管理,资源管理,负载均衡,每日合并调度,迁移复制等。
1.1 节点状态监控
-
lease_time:当 Root Service 累计超过 lease_time 时间(默认10s)没有收到过某节点的任意心跳数据包时,Root Service 认为该 observer 进程短暂断线,Root Service 会标记该节点的心跳状态为 lease_expired。
-
server_permanent_offline_time:当Root Service累计超过 server_permanent_offline_time时间(默认3600s)没有收到过某节点的任意心跳数据包时,Root Service认为该observer进程断线,Root Service会标记该节点的心跳状态为 permanent_offline。
-
OBServer心跳数据包存在,心跳数据包中的 OBServer 磁盘状态正常。此种状态下,Root Service 认为OBServer处于正常工作状态。
-
OBServer心跳数据包存在,心跳数据包中的OBServer磁盘状态异常。此种状态下,Root Service认为observer进程还在,但OBServer磁盘故障。此种状态下,Root Service会尝试将该OBServer上的全部leader副本切走。
-
OBServer心跳数据包不存在,OBServer心跳数据包的丢失时间还比较短,OBServer心跳状态为lease_time,此种状态下,Root Service仅将OBServer的工作状态设置为inactive,不做其他处理。
-
OBServer心跳数据包不存在,OBServer心跳数据包丢失时间超过server_permanent_offline_time,OBServer的心跳状态为permanent_offline,此种情况下,Root Service会对该OBServer上的数据副本进行处理,将该OBServer上包含的数据副本从Paxos成员组中删除,并在其他可用OBServer上补充数据,以保证数据副本Paxos成员组完整。
1.2 节点隔离
ODP(OBProxy)会感知OBServer的异常状态,例如stopped(ACTIVE 状态且stop_time字段大于0)状态、INACTIVE 状态等,从而避免将应用流量路由到异常节点上。如果某个节点网络不稳定、存在响应慢等异常情况,客户端连接该节点后业务侧也会出现不稳定。OceanBase数据库中提供了STOP SERVER命令用于隔离节点。隔离后,该节点不会对外提供服务,ODP 也不会把请求路由到该节点上,可以安全的进行诊断/替换/维修等动作。
-
非通断型故障(例如网卡丢包导致的机器不稳定)强依赖节点隔离,否则会发生反复切主而影响应用。
-
通断型故障(例如机器直接宕机)不强依赖节点隔离,其会在oceanbase.DBA_OB_SERVERS视图标记节点状态为INACTIVE而隔离应用流量。
1.3 故障节点恢复
-
故障节点可以重新启动。这种情况下,不论故障机器之前处于那种心跳状态,重新启动后,OBServer节点与Root Service之间的心跳数据包恢复以后,节点可重新提供服务。
-
故障节点损坏,无法重新启动。这种情况下,在确认节点损坏无法重新启动后,需要数据库管理员执行集群管理操作,将该节点中删除。
2、GoldenDB数据库
DN节点上部署有MySQL和dbagent,其中dbagent就是对MySQL进行周期性检测的组件。Dbagent根据相关配置,对MySQL进行检测,相关配置在dbagent.ini中。DBagent会上报心跳信息到管理节点CM,由CM统一进行故障节点的切换处理。
2.1 周期性检查
Dbagent按照配置的周期,对于mysql进行周期性的检查,根据检查结果设置DB不同的状态,并周期性的将状态上报给CM。CM再根据不同的状态,进行不同的动作。监控周期配置参数:monito_interval,默认为5s。
2.2 长短连接
-
长连接主要是用来执行探测的SQL,根据执行结果判断MySQL是否OK;
-
短连接主要用来进行MySQL连接,判断MySQL是否可以建链
建立连接超时时间由参数控制:connect_database_timeout=40
2.3 探测MySQL
-
长连接正常+短连接正常,记为状态A
-
长连接正常+短连接异常,记为状态B
-
长连接异常+短连接正常,记为状态C
-
长连接异常+短连接异常,记为状态D
优先使用窗口策略(即检查时间点落在配置项monitor_loose_period时间段区间内),长短连接有一个异常(即为状态BCD中任何一种),则放大阈值,其值为两个配置项乘积(connect_test_try_max_times*monitor_loose_times),当失败次数累加值达到阈值,且配置项monitor_kill_db_after_detect_fail为1,则kill db;
非窗口期内则采用收缩策略,状态为B或C则放大阈值,其值使用两个配置项乘积(connect_test_try_max_times*monitor_enlarge_times);状态D则收缩阈值,其值为配置项connect_test_try_max_times的值,并重置B/C状态的失败累加计数器,当失败次数累加值达到阈值,且配置项monitor_kill_db_after_detect_fail为1,则kill db;跳转到状态A,清理BCD状态的历史失败累加值。
monitor_loose_period默认值在00:00:00~00:00:00、monitor_loose_times默认值为10、monitor_enlarge_times默认值为50.
2.4 备机复制关系
Dbagent在监控备机的时候,还会监控备机的复制关系。通过show slave status命令获取到当前复制关系和状态,并上报到CM节点,如果发现复制关系有异常,尝试重试启停复制关系并尝试自动修复。
2.5 DN节点主备故障
-
检测dbagent心跳的周期:参数check_lost_heartbeat_interval,默认值为10s
-
允许丢失dbagent心跳的次数:参数max_allow_loss_heartbeats_times,默认值为3
3、TiDB数据库
TiDB数据库中的PD(Placement Driver)是整个集群的元信息管理模块,负责存储每个TiKV节点实时的数据分布情况和集群的整体拓扑结构。PD还会根据TiKV节点实时上报的数据分布状态,下发数据调度命令给具体的TiKV节点。
-
TiKV节点与PD之间的心跳包,包括节点的存活状态、是否有新的节点加入,以及状态信息,包括:磁盘容量、Region数量、数据读写速率、Snapshot数量、是否过载以及label标签信息
-
Region状态信息,包括Leader的位置、Follower位置、掉线副本的个数、数据读写速率。

-
Up:表示当前的 TiKV Store 处于提供服务的状态。
-
Disconnect:当PD和TiKV Store的心跳信息丢失超过20秒后,该Store的状态会变为Disconnect状态,当时间超过max-store-down-time指定的时间后,该Store会变为Down状态。
-
Down:表示该TiKV Store与集群失去连接的时间已经超过了max-store-down-time指定的时间,默认30分钟。超过该时间后,对应的Store会变为Down,并且开始在存活的Store上补足各个Region的副本。
-
Offline:当对某个TiKV Store通过PD Control进行手动下线操作,该 Store 会变为 Offline 状态。该状态只是 Store 下线的中间状态,处于该状态的Store会将其上的所有Region搬离至其它满足搬迁条件的Up状态Store。当该Store 的leader_count和region_count均显示为 0 后,该Store会由Offline状态变为Tombstone状态。在Offline状态下,禁止关闭该 Store 服务以及其所在的物理服务器。下线过程中,如果集群里不存在满足搬迁条件的其它目标 Store(例如没有足够的 Store 能够继续满足集群的副本数量要求),该 Store 将一直处于 Offline 状态。
-
Tombstone:表示该TiKV Store已处于完全下线状态,可以使用 remove-tombstone 接口安全地清理该状态的 TiKV。
另外,PD 还可以通过扩展的接口接受额外的信息,用来做更准确的决策。比如当某个 Store 的心跳包中断的时候,PD 并不能判断这个节点是临时失效还是永久失效,只能经过一段时间的等待(默认是 30 分钟),如果一直没有心跳包,就认为该 Store 已经下线,再决定需要将这个 Store 上面的 Region 都调度走。
TiDB v6.4.0 全面优化了 TiKV 节点的状态检测机制。即使在磁盘故障或 I/O 无响应等极端情况下,TiDB 依然可以快速上报节点状态,同时搭配主动唤醒机制,提前发起 Leader 选举,加速集群自愈。
4、GaussDB数据库
GaussDB(for openGauss)通过集群管理组件CM server和CM agent来进行集群的管理。CM组件提供了四种服务CM Agent、CM Server、OM Monitor、cm_ctl,与各类实例服务组件(CN, DN, GTM 等)一起构成了整个数据库集群系统。
4.1 CM运行流程
4.1.1 cm_server功能
cm_server是集群 管理的大脑,整个管理系统的仲裁者,系统中只有一个,主备架构,系统中常驻的服务进程,多线程架构。主要收集cm_agent返回的各个实例(GTM主备、CN、DN主备从)状态信息,从而通过分析给出谁是主谁是备,什么时候需要failover切换,什么时候需要重建DN。cm_server的另一个作用就是接收客户端cm_ctl发送的命令,使得cm_ctl可以管理整个集群。
4.1.2 cm_agent功能
cm_agent负责收集本地内核端各个组件的状态信息,并上报给CMserver。CMagent本地并不存储任何信息,是一个无状态的组件,进程故障后,可以由OM monitor立刻拉起。
4.1.3 om_monitor
om_monitor进程负责拉起cm_agent以及杀掉非自己启动的cm_agent。om_monitor为了保活,每分钟都会被系统定时任务crontab拉起,后拉起的进程在发现已经有om_monitor进程时,会自己退出。
4.2 CM告警机制
-
当cm_agent检测到dn或gtm实例状态异常并上报给cm_server之后,会做一些检查以及启动实例,会根据实例心跳超时时间(instance_heartbeat_timeout,默认值6s)进行判定,当超过实例心跳时间之后实例无法恢复,cm_server会给cm_agent下发仲裁命令,将相应实例的状态置为Unknown。
-
当cm_agent检测到cn实例状态异常之后,会做一些检查以及启动实例,会根据cm_server在CN故障后仲裁自动剔除的触发时间(coordinator_heartbeat_timeout,默认值25s),当超过该时间实例无法恢复,自动剔除cn。
-
当cm_server未收到cm_agent的上报,会根据实例心跳超时时间(instance_heartbeat_timeout)进行判定,当超过实例心跳时间之后依旧无法恢复cm_server与cm_agent的连接,cm_server会给其他cm_agent下发主备切换,将相应实例的状态置为 Unknown。
4.3 异常检测
-
CM Agent和实例之间建立长连接,当长连接断开直到超出心跳时间,cms发送failover命令到备节点,触发主备切换;
-
短连接检测中CM Agent按照固定时间间隔与DN实例新建链接。如果与某个主DN链接失败或通过新链接无法执行SQL语句,则认为该DN发生1次Hang异常。如果多次出现异常(instance_keep_heartbeat_timeout,默认值40s),则会触发Hang检测机制,将该DN实例杀死并执行主备切换。目前常见的异常检测项有:短连接建立、短连接执行SQL语句异常、IO挂死和内存异常等。
4.4 故障恢复
-
CN节点故障:将故障CN节点剔除
-
DN节点故障:主DN故障时,仲裁备DN升主继续提供服务;备DN故障时,主DN将日志和数据同步至从备,业务不受影响
-
主GTM故障:备GTM升主后继续提供服务
-
主CM Server故障:备CM Server接受多数派CM Agent链接,升主后继续提供服务
-
CM Agent 1探测DN主实例并发现故障
-
CM Agent 1持续上报实例故障信息至CM Server
-
CM Server执行仲裁流程,选择DN备机升主
-
CM Server下发升主命令至CM Agent 2
-
CM Agent 2对实例执行升主操作
5、TDSQL数据库
5.1 TDSQL架构

-
监控MySQL的实例是否能够正常的运行,及时上报实例异常的信息,便于Scheduler模块判断是否需要进行容灾切换,同时会监测是否有容灾切换的任务
-
监测MySQL实例的资源利用率、各个表的请求量和数据量,并上报到Zookeeper。Scheduler模块根据资源的使用情况判断是否需要进行扩容或者缩容;同时会监测是否有扩容或缩容的任务下发
-
监测主从复制和数据同步的情况,定期上报主备复制的延时和延迟的事物数,如果发生了主备切换会自动向新主机重建主备
-
迁移、配置文件修改、表一致性校验、binlog镜像备份等任务的检测
Agent会尝试通过Socket连接DB、写DB和读取DB,如果这三个操作中有一个不成功即上报存活状态异常,Scheduler会根据异常信息进行容灾切换。Agent在Zookeeper中存储的节点类型是临时节点,当Agent出现异常临时节点会消失,此时Scheduler会检测到对应的异常并处理。Scheduler控制整个切换的流程,Scheduler会分析Agent上报上来的心跳信息,决策是否进行主备切换,控制切换流程。
5.2 主从切换流程
-
读心跳表,检查是否可读(长连接)。
-
写心跳表,检查是否可写(长连接)。
-
尝试建立到mysqld的新TCP连接,检查mysqld是否能接受新连接。
-
心跳节点正常上报,zookeeper中hb心跳内容明确展示mysqld异常。该情况处理比较简单,直接根据心跳内容来判断即可。
-
心跳节点无法上报,zookeeper中hb心跳内容的临时节点丢失,即hb@xxx的信息丢失。
-
当set主节点异常(心跳丢失和心跳内容错误),scheduler开始计时(schedule本机时间减hb心跳时间);当set主节点心跳在maxlosthbtime(默认20s)时间内没有恢复时,则scheduler开始触发主从切换。
-
切换前,先检测当前实例是否处于免切状态(整个集群手动免切、set手动免切、set自动免切)。如果处于免切状态,并且在有效时间窗口内,则不触发主从切换,同时将不切换原因入库。
-
判断当前set是否为扩容、回档、dcn数据同步等状态(setrun中的kpstatus值),如果是则不触发主从切换。
-
统计同IDC与跨IDC的存活强同步从机个数;这里存活的定义是:alive为0,同时election为true。同时检测watch节点中是否存在standby_watch,如果存在,并且时间小于30s,则可以作为选举从机节点。
6、总结
-
OceanBase数据库通过Root Service接收节点的心跳信息,在心跳信息中包含有磁盘的状态信息。当磁盘故障时,Root Service会尝试将该OBServer上的全部leader副本切走。也就是OB数据库对磁盘异常这一故障场景做了处理。
-
GoldenDB数据库通过长连接和短连接的方式,将心跳信息上报给CM节点。针对磁盘异常或IO慢的场景,心跳中没有明确的信息给到CM节点进行判断,因此在磁盘异常导致的IO夯住等场景下,故障的恢复时间变长;
-
TiDB数据库将心跳信息上报给PD,出现异常时由PD触发调度策略。TiDB在6.4版本后,增加了在磁盘故障或 I/O 无响应等极端情况下,TiDB快速上报节点状态,同时搭配主动唤醒机制,减少故障恢复时间。
-
GaussDB数据库通过cm_agent将心跳信息上报到cm_server,故障检测的场景包括磁盘故障和慢盘等场景
-
TDSQL数据库也是通过agent对mysql进程的长短连接的方式,上报心跳信息。针对磁盘故障IO夯住这一类场景,故障恢复时间也将变长。
参考资料:
-
https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000640611
-
GoldenDB数据库高可用切换机制
-
https://docs.pingcap.com/zh/tidb/stable/tidb-scheduling
-
https://bbs.huaweicloud.com/blogs/224005
-
https://cloud.tencent.com/privatecloud/document
-
https://blog.51cto.com/u_15721050/6038871
原文始发于微信公众号(牧羊人的方向):国产分布式数据库高可用故障检测能力
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/289638.html