首批通过分布式安全可靠测评,为关键业务系统打造
RS 自检手段
更新时间:2024-09-13 04:06
背景
目前,OceanBase 集群的稳定性依靠 RS 稳定,如果 RS 启动失败或者运行卡住则可能影响系统可靠性可用性,例如:RS 长时间不推 snapshot_gc_ts 会导致内存或者磁盘爆,长时间不合并会导致磁盘爆,RS 无法工作用户就不能做 DDL 等等。因此,线上自愈系统希望有一套检测机制,能通过该机制发现 RS 的异常,并通过运维命令强制切换 RS 来恢复。
目前还没有相关的检测机制,但是可以在特定场景下增加一些统计机制,并且通过日志或者内部表的方式输出,监控系统可以通过这些日志来判断 RS 是否出现异常,通知运维干预。
检测机制
RS 无主
__all_core_table 无主时,RS 就会无主。说明 election 模块出了问题,需要人工上线处理。
检测方法:
搜索 election.log 日志文件
leader_revoke, please attention日志,过滤是否是__all_core_table的告警日志:1099511627777。grep 'leader_revoke, please attention' election.log* | grep 1099511627777如何确认是
__all_core_table无主:登录 SYS 租户,查询__all_core_table。如果登录失败,或者查询__all_core_table失败,则认为是__all_core_table无主。处理方案:需要隔离有问题的 server,上线处理。
RS 上任失败
__all_core_table 有主后,RS 会上任,上任过程中可能会失败,例如内部表不可读写。如果连续 N 次上任失败,则需要报警。
在 RS 上任过程中可查询内部表 __all_virtual_core_meta_table,如果内部表 __all_virtual_core_meta_table 查询超时,代表 RS 可能没有上任成功,此时再去查找日志。
实现上,每次上任失败都打印 WARN 日志,超过 10 次重试上任失败后,打印 ERROR 日志。
检测方法:格式化日志:
rs_monitor_check : fail to start root service(ret=errcode, ret=errname, fail_count=N)//上边的格式化日志是个性化的部分,真实的日志实例如下: [2020-04-24 10:32:14.074595] ERROR [RS] update_fail_count (ob_root_service.cpp:12617) [16125][140][Y35480B9E29E3-0005A4002C28251E] [lt=5] rs_monitor_check : fail to start root service(ret=-4165, ret="OB_EMPTY_RESULT", count=11) BACKTRACE:0x116878e6 0x11521c53 0x5b31608 0x7944ced 0x78a2b3e 0x789e729 0x78dfa10 0x1158222c 0x1158d382 0x7fa472b 0x1158ccb4 0x36c02e6 0x36c0244 0x36e7478 0x36e731d 0x2f7129e 0x1129b1e4 0x11296e75 0x1129a98f处理方法
请联系技术支持人员处理。
RS 线程卡住
RS 上存在多个线程,负责在 RS 服务启动期间提供各种服务,比如:负载均衡、每日合并、回收快照点等。可以关键字搜索ObRsReentrantThread 来定位这些线程。 基本上,这些线程如果卡住,对系统都会带来一定的稳定性影响。因此,可以监控这些线程运行情况,如果长时间不继续运行则说明线程已经卡住了。
| 线程类名 | 线程名字 | 用途 | 线程调度周期 |
|---|---|---|---|
| ObDailyMergeScheduler | DayMergeSch | 每日合并调度线程 | 10m |
| ObFreezeInfoUpdater | FrzInfoUpd | 冻结信息和快照回收点更新线程 | 1s |
| ObLeaderCoordinator | LeaderCoord | Leader均衡线程 | 30s |
| ObMajorFreezeLauncher | MajorLaunch | 大版本冻结发起线程 | 1s |
| ObRebalanceTaskMgr | RebTaskMgr | 负载均衡任务管理线程 | 1s |
| ObRootBalancer | RootBalance | 负载均衡线程 | 由balancer_idle_time配置项控制,默认5分钟 |
| ObHeartbeatChecker | HBChecker | server心跳检测线程 | 0.1s |
检测方法:如果线程超过调度时间 10 分钟不调度,则打印 ERROR 告警日志。
rs_monitor_check : thread hang(thread_name=线程名字, last_run_timestamp=xxxx, last_run_interval=xxx, check_interval=xxx, schedule_interval=xxxx)其中:
- last_run_timestamp:上次运行时间。
- last_run_interval:日志打印时间-上次运行时间。
- check_interval:日志告警时间间隔阈值。
- schedule_interval:线程调度间隔。
真实日志如下:
[2020-04-16 21:06:11.717849] ERROR [SERVER] monitor_root_service (ob_root_service_monitor.cpp:131) [21943][1579][Y0-0000000000000000] [lt=15] [dc=0] rs_monitor_check : thread hang(thread_name=FrzInfoUpd, last_run_timestamp=1587455411540103, last_run_interval=1579001, check_interval=1500000, scheduler_interval=1000000) BACKTRACE:0x7f491212228b 0x7f491205cbb2 0x7f490920113f 0x7f491083ef7e 0x7f491083e938 0x7f49099018df 0x7f49096467f9 0x7f490964e0f0 0x7f490964e702 0x7f49094fc500 0x7f49121d4de8 0x7f49121c9b73 0x7f49121d847f处理方案:
可以尝试手动切换 RS 的 leader。
obclient> alter tenant sys set primary_zone = 'xxx';
长时间不做快照点回收
快照回收的线程也属于 Runnable 线程,但光靠上面线程是否卡住的检测是不够的,还需要检查实际执行结果,通过控制 __all_core_table 中 table_name = '__all_global_stat' 的 snapshot_gc_ts 来控制快照点回收的。snapshot_gc_ts 的用途是用来通知 OBS,小于 snapshot_gc_ts 的多版本快照是可以不再保存,这样 OBS 在做 compaction 的时候,就能回收掉历史上的多版本信息,只保存最新的值,减少磁盘占用量。长时间不推 snapshot_gc_ts 会导致多版本的数据太多,不断触发转储,对磁盘有影响,另外查询效率也会变低,容易引起一些列的不良反应。snapshot_gc_ts 一般和当前时间值差不多。如果该值距离当前时间戳太远,比如超过 1 个小时,则可以认为当前系统处于不稳定状态下,需要报警接入。
但是这里要额外考虑一下备库快照接入的场景,备库快照接入的期间,当副本还没有拷贝齐全的时候,snapshot_gc_ts 是不会继续推进的,这个时间段可能持久较长时间,但是不需要报警。
检测方法:
检查 snapshot_gc_ts 值,如果半个小时不推进打印 WARN 日志,1 个小时不推进打印 ERROR 日志。另外,只需要关心
cluster_type=PRIMARY的 snapshot_gc_ts 即可,备库的 snapshot_gc_ts 暂时不需要关心。rs_monitor_check : snapshot_gc_ts delay for a long time(snapshot_gc_ts=xxxx, delay=xxx, cluster_type = PRIMARY)真实日志如下:
[2020-04-24 10:38:54.755687] ERROR [RS] check_snapshot_gc_ts (ob_freeze_info_manager.cpp:1071) [17969][160][Y35480B9E29E3-0005A400410A8EA3] [lt=9] rs_monitor_check : snapshot_gc_ts delay for a lone time(snapshot_gc_ts=1587695929741814, delay=5013608009) BACKTRACE:0x116878d6 0x11521c43 0x2e36382 0x6814a1d 0x6814784 0x8039760 0x66776bd 0x1158d372 0x803ac2b 0x1158cca4 0x36c02e6 0x36c0244 0x36e7478 0x36e731d 0x2f7129e 0x1129b1d4 0x11296e65 0x1129a97f处理方法:如果发现 snapshot_gc_ts 长时间不推进,则联系技术支持人员处理。
另外,__all_acquired_snapshot 这张表也是用来保存快照点的,在建索引的时候,会将快照点保存在这个表。理论上,只需要包括当前快照点上的数据即可,但是目前 OBS 层的实现限制,会把快照点和之后所有的快照版本都保留下来。这张表中包括的快照点也需要进行检查,但是这个快照点的检查时间较上面的时间要宽裕一些,因为这个时长受建索引的时长影响,同时这个快照点也只影响需要建索引的单个表。
检查索引状态,如果索引生效,则删除快照点;如果索引不生效,删除索引和对应的快照点。
长时间不合并
OceanBase 集群默认每天都需要合并一次,如果长时间不合并会影响磁盘占用率,使集群变得不稳定;监控系统可以从 __all_zone 表中查出最新一次的合并时间,超过 1 天不合并,则需要报警。
检测方法:
从
__all_zone表查最新一次合并时间,超过1天不合并,自愈系统干预。(目前自愈系统已经具备该能力)处理方案:
人工确认后在低峰期手动发起合并;或者等待下一轮合并;如果手动发起失败,则联系技术支持人员处理。
工作队列满
有关工作队列满的排查情况,可参考文档 如何排查租户队列积压
适用版本
OceanBase 数据库 V2.x、V3.x 版本。