写点什么

【SOP】最佳实践之 TiDB OOM 分析

  • 2023-11-24
    北京
  • 本文字数:4190 字

    阅读完需:约 14 分钟

作者: Jellybean 原文来源:https://tidb.net/blog/5e10a92c



大家可能经历过这样一个场景,在某个正在熟睡的凌晨突然收到告警电话有 tidb-server 节点频繁重启,可能还伴随有内存告警,然后赶紧起来排查确认。上线一看发现不少节点出现了 OOM ,类似上图,在找到对应的 SQL 和业务一确认后,确定是凌晨偷偷新上的统计任务导致了这次的问题,赶紧让业务先停掉完,告知业务完成优化且经过 DBA 确认后再另外排期上线,之后骂骂咧咧的再次滚回被窝去。这个案例起码至少说明了几个问题:


  • 开发能力和开发规范遵循问题

  • 上线流程控制问题

  • 数据库自身资源管控问题


在问题出现后数据库管理员总结排查方法,还可以针对性的做好开发手册指引和培训工作。


而我们在 TiDB 的使用过程中,尤其是访问大量数据的分析型业务场景,很难不会遇到 OOM 的问题。OOM 的问题一旦出现,集群必然会受到影响,所以,这就要求我们能够以尽快的速度完成排查和处理。本文这里总结一些日常管理 TiDB 集群的经验,方便后面遇到类似问题时可以作为一个排查思路和操作指引,协助快速处理 OOM 问题。

是不是 OOM 问题?

有收到内存告警、节点卡住或重启的情况,我们可以在脑海中有个初判会不会是 OOM 问题。TiDB 集群 OOM 通常出现在 tidb-server 节点上,也有少数情况出现在 tikv-server 节点。大致可以先通过下面的分析流程进行排查,确认是不是 OOM 的问题。



如上图所示,我们遇到问题后可以有下面的分析来确认是不是具体组件出现了 OOM 。


是不是 tidb server OOM 问题


  • 业务侧、用户端:

  • 部分访问有明显延迟 

  • 部分业务有 lost connection 的报错

  • grafana 监控:

  • uptime 出现掉线重启 

  • Overview->TiDB->Memory Usage 出现高峰急剧掉线重启

  • tidb server 日志:

  • tidb.log 在问题时段出现 Welcome 重启关键字 

  • tidb_stderr.log 有 oom 或 can not allocate memory 关键字

  • 系统日志

  • tidb server 节点系统日志 dmesg -T| grep tidb-server 在问题时段附近有 OOM Killer 出现



(图片来源https://tidb.net/blog/de9bf174


是不是 tikv server OOM 问题


  • 业务侧、用户端:

  • 集群访问延迟有突增

  • 业务 QPS 有明显抖动

  • grafana 监控

  • tikv detail->cluster->uptime 出现掉线重启

  • tikv detail->cluster->memory 面板看到有 tikv 实例的内存剧烈上升后突然掉零再慢慢增加,可判断为 tikv OOM 重启了

  • tikv server 日志

  • 排查 tikv.log 日志,在问题时段附近有 Welcome 实例重启标记

  • 系统日志

  • dmesg -T| grep tikv-server 在问题时段有 OOM-killer 日志

OOM 原因是什么

当遇到 OOM 的问题之后,排查触发原因时,大致可以分为两类原因:


  • 数据库原因导致的 OOM

  • 非数据库原因导致的 OOM


数据库本身导致的 OOM 问题,通常是统计信息不准确导致执行计划问题、集群配置参数使用不当等引起情况。非数据库原因导致的 OOM 问题,通常可以归类为硬件资源不足、混合部署等原因,比如其他应用进程抢占了过多的内存资源导致 TiDB 被系统的 oom-killer 直接干掉。

OOM 如何处理

针对不同的 OOM 触发根因,我们会有不同的处理策略。

如何处理 tidb server 的 OOM 问题

非数据库原因

  • 机器内存不足

  • 确认部署 tidb server 的机器操作系统内存是否太少,导致内存不足。开发及测试环境建议值是 16 GB+,生产环境建议值是 48 GB+。

  • https://docs.pingcap.com/zh/tidb/v7.4/hardware-and-software-requirements

  • 集群混部问题

  • 排查是不是部署过多的实例节点,如果节点个数太多也容易引起 OOM。生成环境下内存 128 GB 的机器,通常建议部署 2 个 tidb server 节点就够了。可以考虑通过增加 cgroup 策略来进行资源划分。

  • 排查 tidb server 是不是和 tikv server 混合部署,如果是也有可能会有内存相互挤兑从而触发问题。可以考虑通过增加 cgroup 策略来进行资源划分。

  • 确认是否有业务进程混合部署,导致内存资源挤兑。应该专机专用,不部署业务程序。

数据库原因

如果发现内存正在上涨还没有出现 OOM 但是也有 OOM 的风险,可以根据下面的方式获取相关信息来分析:


  • 查看当前链接的内存使用情况

  • 执行 SELECT * FROM information_schema.processlist; 查看 SQL 对应的 MEM 列的值,定位到使用内存最多的语句。

  • 执行以下命令收集内存使用率高的 tidb server 的 Profile 信息

  • curl -G http://{TiDBIP}:10080/debug/zip?seconds=10” > tidb_server_profile.zip


原因判断和处理:


  • 问题 SQL 定位

  • 获取可能的问题 SQL,可以查看 INFORMATION_SCHEMA 中的 SLOW_QUERY 和 CLUSTER_SLOW_QUERY 。


  • 也可以通过 tidb dashboard 的 慢 SQL 和 SQL 语句找到问题附近的 SQL 并分析,定位到具体的问题 SQL,从 SQL 语句分析、慢查询的具体内容,可以详细查看内存使用量。

  • 同时 grep expensive_query tidb.log 辅助定位问题时间点的 SQL 情况。

  • 如果确认是 SQL 的执行计划有问题,如缺少合适索引、统计信息过期、优化器 bug 等原因,很可能会导致选错执行计划而导致大量中间结果数据累积在内存,出现 OOM。

  • 可以添加合适索引、使用 analyze 重新收集统计信息等措施进行处理。

  • 如果确认 OOM 时是系统在收集和加载统计信息的过程中消耗太多内存。

  • 可以指定采样率、指定只收集特定列的统计信息、减少 ANALYZE 并发度等方式减少内存使用。

  •  v6.1.0 以后引入了系统变量 tidb_stats_cache_mem_quota对统计信息的内存使用进行限制,引入了系统变量 tidb_mem_quota_analyze控制 TiDB 更新统计信息时的最大总内存占用。

  • 如果 OOM 问题发生时间附近,tidb session 的并发度过高或者某些节点的连接数过多。

  • 需要扩容或优化负载均衡策略。

  • 查看执行计划,如果发现存在算子 HashAgg 处理大量数据。

  • HashAgg 是多线程并发执行,虽然执行速度较快,但会消耗较多内存,可以尝试使用 STREAM_AGG() 替代。

  • 如果出现 OOM 问题时段附近,业务访问有大事务或大写入,导致消耗太多内存。

  • tidb server 在执行事务时 TiDB 进程的内存消耗相对于事务大小会存在一定程度的放大,最大可能达到提交事务大小的 2 到 3 倍以上。

  • 所以针对单个大事务,可以通过拆分的方式调小事务,可能需要和业务沟通调整程序。

  • 排查和调整 tidb server 的配置参数

  • 设置单条 SQL 使用的内存上限。

  • 可以调整 session 级别参数 tidb_memory_quota_query 参数限制单条 SQL 语句的内存使用量,默认值为 1GB

  • 设置单个 tidb-server 节点使用的内存上限。

  • v6.5.0 以后可以通过系统变量 tidb_server_memory_limit 设置 tidb-server 实例的内存使用阈值,默认为总内存的 80%。

  • TiDB 会在内存用量达到该限制时对当前内存用量最高的 SQL 语句 Cancel,然后会尝试调用 Golang GC 立刻回收内存,以最快速度缓解内存压力。

  • 一次只能 Cancel 一条 SQL 语句。如果 TiDB 完全 Cancel 掉一条 SQL 语句并回收资源后,内存使用仍然大于该变量所设限制,TiDB 会开始下一次 Cancel 操作。被强制终止的 SQL 操作会向客户端返回报错信息 Out Of Memory Quota!。

  • 使用系统变量 tidb_mem_oom_action 来控制单条查询超过内存限制后所采取的操作是 CANCEL 还是 LOG。

  • CANCEL 则会中断查询并打印相关日志。

  • LOG 则不会中断查询,仅仅记录相关内存使用信息。

  • 设置数据落盘

  • HashAgg 落盘功能目前不支持 distinct 聚合函数。使用 distinct 函数且内存占用过大时,无法进行落盘。


  • 当 SQL 的内存使用超过 Memory Quota 时,tidb-server 可以通过落盘执行算子的中间数据,缓解内存压力。可以启用临时磁盘 oom_tmp_storage ,指定路径 tmp_storage_path 和使用外部磁盘的空间上限 tmp_storage_size。

  • 当包含 HashAgg 算子的 SQL 语句引起内存 OOM 时,TiDB 默认不触发落盘,可以通过设置系统变量 tidb_executor_concurrency = 1 来触发 HashAgg 落盘的功能。

如何处理 tikv server 的 OOM 问题

非数据库原因

  • 机器内存不足

  • 确认部署 tikv server 的机器操作系统内存是否太少,导致内存不足。开发及测试环境建议值是 32 GB+,生产环境建议值是 64 GB+。

  • https://docs.pingcap.com/zh/tidb/v7.4/hardware-and-software-requirements

  • 集群混部问题

  • 排查是不是部署过多的实例节点,如果节点个数太多也容易引起 OOM。可以考虑通过增加 cgroup 策略来进行资源划分。

  • 排查 tikv server 是不是和 tidb server 混合部署,如果是也有可能会有内存相互挤兑从而触发 OOM 问题。可以考虑通过增加 cgroup 策略来进行资源划分。

  • 确认是否有业务进程混合部署,导致内存资源挤兑。其他进程占用过多内存,也可能会导致系统误杀 tikv 进程。应该专机专用,不部署业务程序。

数据库原因

  • 排查 block cache 参数配置是否合理。通过查看 TiKV Detail  -> RocksDB KV -> Block cache size 面板查看内存使用变化。

  • 如果是 block cache 的问题,则合理调整 storage.block-cache.capacity 参数大小,默认为系统内存的 45%,通常可以设置范围为 45%-60%,配置过高导致容易 OOM。如果是多个节点同时部署的时候,尤其要注意该参数的配置,可以设置 storage.block-cache.capacity = (MEM_TOTAL * 0.5 / TiKV 实例数量)。

  • https://docs.pingcap.com/zh/tidb/stable/hybrid-deployment-topology

  • 在 v6 以后的版本支持在 MySQL 终端在线修改该参数 set config tikv xxxx=xxxx (推荐);或者 tiup cluster edit-confg xx 编辑修改再 reload 重启 tikv 实例。



  • 确认是否因为读取大量数据导致 OOM 。查看 tikv details 的 copprocessor 面板,以及查看 node-exporter 的 network 面板查看 gRPC 的网络传输量,确认是不是远远小于 copprocessor 读取的数据量。

  • 如果是 copprocessor 读取大量数据而 gRPC 来不及消费传送到 TiDB server,说明有大 SQL 出现导致 copprocessor 读取大量数据到 tikv 的 block cache 中而 gRPC 来不及消费传送到 tidb,会导致数据堆积过多而 OOM。此时可以采取下面的处理措施:

  • 优化 SQL 使得一次性不读取大量数据。

  • 如果机器使用的是千兆网卡,则建议升级为万兆网卡。


对于 TiKV OOM 的分析,社区里 h5n1 大佬的这篇文章也非常推荐阅读 https://tidb.net/blog/ab528ebf

总结

TiDB 出现 OOM 问题,最频繁的节点是在 tidb server 中,而引起问题的最多原因是因为大 SQL 或执行计划不准。


而 tikv 出现 OOM 的问题,大多数是因为 block cache 配置问题引起,在部署和排查时可以重点关注该方面问题。


我们在日常运维管理工作中,针对这些场景有一定的提前规划和准备,即可从容应对大部分的 OOM 问题。


社区也有不少很不错的 OOM 排查实践案例,在遇到问题时可以一并参考。


发布于: 刚刚阅读数: 3
用户头像

TiDB 社区官网:https://tidb.net/ 2021-12-15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
【SOP】最佳实践之 TiDB OOM 分析_性能调优_TiDB 社区干货传送门_InfoQ写作社区