---
title: RS 自检手段-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 RS 自检手段相关的常见问题和使用技巧，帮助您快速解决 RS 自检手段的难题。
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# RS 自检手段

更新时间：2024-09-13 04:06

适用版本： V2.1.x、V2.2.x、V3.1.x、V3.2.x 内容类型：Troubleshoot  

## 背景

目前，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。

  ```shell
  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 日志。

- 检测方法：格式化日志：

  ```shell
  rs_monitor_check : fail to start root service(ret=errcode, ret=errname, fail_count=N)

  ```

  ```shell
  //上边的格式化日志是个性化的部分，真实的日志实例如下：
  [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 告警日志。

  ```shell
  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：线程调度间隔。

  真实日志如下：

  ```shell
  [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。

  ```shell
  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 暂时不需要关心。

  ```shell
  rs_monitor_check : snapshot_gc_ts delay for a long time(snapshot_gc_ts=xxxx, delay=xxx, cluster_type = PRIMARY)

  ```

  真实日志如下：

  ```shell
  [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天不合并，自愈系统干预。（目前自愈系统已经具备该能力）
 - 处理方案：

  人工确认后在低峰期手动发起合并；或者等待下一轮合并；如果手动发起失败，则联系技术支持人员处理。

### 工作队列满

有关工作队列满的排查情况，可参考文档 [如何排查租户队列积压](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000813134)

## 适用版本

OceanBase 数据库 V2.x、V3.x 版本。

上一篇

[RTO 耗时长排查文档](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000817255)

下一篇

[leader 节点一台主机 hang 时可能不触发无主选举导致整个集群不可用](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000002395808) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
