tidb-in-action

7.4 TiDB OOM 的常见原因

日常 TiDB 运维中,会遇到组件 OOM 的问题,通常出现在 TiDB-Server 和 TiKV-Server,分别来看一下出现的常见原因以及处理建议。

7.4.1 TiDB-Server

1. 如何快速确认 TiDB-Server 出现了 OOM

2. TiDB-Server 出现 OOM 的常见原因

导致 TiDB oom 的本质原因是 TiDB 现有的内存小于 TiDB 要使用的内存。

SQL 执行计划中的 root 任务占比过高,TiDB-Server 需要缓存大量数据。比如执行计划中使用了 hash join、过多的子查询、Update&Delete 涉及数据量过大等等。

3. 如何缓解 TiDB-Server OOM 问题

1)优化单一大 SQL
     当出现 TiDB OOM 时 ,去查看对应的 tidb_slow_query.log 通过 Query_time 和 Mem_max 值定位使用内存过多的慢 SQL 。
     如果是查询 SQL 可通过其执行计划定位,是否存在着以下动作:
     全表扫描 table scan 优化思路:考虑新建索引。
     hash join 优化思路:注意表之间的排列顺序,让筛选性好的表优先 join ;考虑使用 index loop join 代替。
     如果是 delete 语句,可以考虑使用 tidb_batch_delete 方式,或业务上分片方式,达到少量多次的效果。
2)横向扩容 TiDB 
     面对没有单一大 SQL ,而是并发较高的场景,可以选择横向扩展 TiDB 节点来缓解单一 TiDB 实例的压力,从而起到缓解 oom 的作用。

7.4.2 TiKV-Server

TiKV-Server OOM 的常见场景有如下几种,不同场景的处理建议也有不同。

1. block-cache 配置过大

在 TiKV grafana 选中对应的 instance 之后查看 RocksDB 的 block cache size 监控来确认是否是该问题。同时检查 参数是否设置合理,默认情况下 TiKV 的 block-cache 设置为机器总内存的 45%,在 container 部署的时候需要显式指定该参数,因为 TiKV 获取的是物理机的内存,可能会超出 container 的内存限制。

[storage.block-cache]
capacity = "30GB"

处理建议:

  1. 适当增大机器内存
  2. 适当减小 block-cache

2. coprocessor 收到大量大查询,需要返回大量的数据

gRPC 发送速度跟不上 coprocessor 往外吐数据的速度导致 OOM。可以通过检查 [tikv-detail]->[Coprocessor Overview]->[Total Response Size] 是否超过 network outbound 流量来确认是否属于这种情况。

处理建议:

  1. 使用万兆网卡,提高数据传输速度
  2. 参照本书 “快速定位慢 SQL” 的章节,检查是否存在全表扫描的大查询
  3. 检查 gRPC poll CPU 是否不足

3. Raft apply 线程短时间需要处理大量 raft 日志,apply log 过程速度慢

Apply 日志不及时可能导致 apply channel 中内存堆积,堆积严重导致系统内存不足则会出现 oom。通常是 apply wait duration 和 apply log duration 过高。相关监控位于: