1. 前言
我在OceanBase问答社区协助用户排查了一个CPU占用率过高的问题,帖子原文是:
《刚刚新安装的OceanBase集群,没有任何数据,CPU占用非常高,这正常吗?》。从这个场景出发,来分享相关的诊断经验,希望能为其他用户提供一些参考和启示。
2. 问题现象
用户的集群创建完成,创建了一个租户,还未曾导入数据,就出现cpu居高不下的情况,如图是其中一个节点的
3. 适用版本
OBServer 2.x版本, OBServer 3.x版本, OBServer 4.x版本
4. 排查过程
- 用obdiag收集了一下cpu高场景的信息obdiag gather scene run --scene=observer.cpu_high,从其中的top.txt信息中看到内核态使用CPU过高。
补充知识:在 Linux 的 CPU 状态信息中发现,有“%us、%sy、%ni、%id、%wa、%hi、%si、%st”等状态。
● us:用户空间占用CPU百分比(Host.cpu.user)
● sy:内核空间占用CPU百分比(Host.cpu.system)
● ni:用户进程空间内改变过优先级的进程占用CPU百分比
● id:空闲CPU百分比(Host.cpu.idle)
● wa:等待输入输出的CPU时间百分比
● hi:硬件中断
● si:软件中断
● st:实时
2. 使用 sudo perf top -p 命令采集到的数据如下图所示:
发现排在第一位置的是read_hpet, 占用了71.13%,而这个read_hpet是和时钟源相关的,有理由怀疑是时钟源导致的节点CPU高。
3. 【扩展排查】通过perf图去看调用关系
可以手动抓取 perf 调用图分析热点函数,步骤如下:
# 生成 perf 调用图
sudo perf record -o perf.data -e cycles -c 100000000 -p $(pidof -s observer) -g -- sleep 20
sudo perf script -i perf.data -F ip,sym -f > data.viz
当然也可以直接用obdiag gather perf命令来执行一键收集,此处省略了perf数据生成图片的操作,感兴趣的可以去查perf官网的资料。
其中热点函数跟 perf top 的结果一致。
查询相关资料,发现在Linux操作系统上tsc是首选时钟源——因为它的开销低很多,而hpet作为后备时钟源。一个千万次事件计数的基准测试显示,TSC花费约0.6秒,而HPET花费略微超过12秒,ACPI电源管理计时器花费约24秒。
4. 确认机器时钟源
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
hpet
问题集群的时钟源为hpet,OceanBase官网文档中推荐时钟源为tsc,当 OBServer 服务器使用 hpet 作为时钟源类型时,获取系统时间的开销会比较大,进而可能导致内核态 CPU 使用率高。
5. 解决办法
方法一:临时切换时钟源
# 第一步,查看当前系统可用的时钟源(输出包含 tsc 方可执行第二步)
cat /sys/devices/system/clocksource/clocksource0/available_clocksource
# 第二步,临时切换时钟源(重启后失效)
sudo bash -c 'echo tsc > /sys/devices/system/clocksource/clocksource0/current_clocksource'
方法二:永久切换时钟源
如果可用时钟源列表中没有 tsc,也能生效,只要 CPU 支持 稳定tsc 特性即可(可通过执行命令 cat /proc/cpuinfo | grep constant_tsc 验证是否支持 ) 。
第一步,执行sudo vi /etc/default/grub。
在原配置行 GRUB_CMDLINE_LINUX 后面的参数值中追加参数设置 clocksource=tsc tsc=reliable clocksource_failover=hpet (表示启用 tsc 作为时钟源,如果 tsc 不可用则用 hpet 兜底)
# 将如上参数配置项修改为如下形式
# 如果之前已经有 clocksource 等参数的,就直接替换
GRUB_CMDLINE_LINUX="原参数设置 clocksource=tsc tsc=reliable clocksource_failover=hpet"
第二步,生成 grub.cfg 文件
grub2-mkconfig -o /boot/grub2/grub.cfg
然后重启系统,以便设置生效。
可通过如下命令行验证当前的时钟源是否修改成功:
# 查看 当前系统的时钟源
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
参考文档:https://repost.aws/zh-Hans/knowledge-center/manage-ec2-linux-clock-source
6. 后续Action
obdiag已收纳该场景的需求,巡检项会在即将发布的obdiag 2.1.0 中带上。CPU场景的经验也会沉淀到obdiag的代码中,敬请期待。
7. 附录
- obdiag 下载地址: OceanBase分布式数据库下载中心
- obdiag 官方文档: OceanBase 敏捷诊断工具(obdiag)文档
- obdiag github地址: GitHub - oceanbase/obdiag: obdiag (OceanBase Diagnostic Tool) is designed to help OceanBase users quickly gather necessary information and analyze the root cause of the problem.
- obdiag SIG 营地: oceanbase-diagnostic-tool · OceanBase 技术交流
-
第一篇 如何修炼成“神医”——《OceanBase诊断系列》之一 第二篇 走进SQL审计视图——《OceanBase诊断系列》之二 第三篇 快速收集诊断信息,敏捷诊断工具obdiag应用实践——《OceanBase诊断系列》之三 第四篇 如何快速分析OB集群日志,敏捷诊断工具obdiag分析能力实践——《OceanBase诊断系列》之四 第五篇 防患未然,OceanBase巡检工具应用实践——《OceanBase诊断系列》之五 第六篇 obdiag帮你读懂全链路诊断日志——《OceanBase诊断系列》之六 第七篇 如何排查合并问题——《OceanBase诊断系列》之七 第八篇 轻松掌握锁冲突问题的排查方法——《OceanBase诊断系列》之八 第九篇 obdiag如何实现一键采集20+故障场景的诊断信息——《OceanBase诊断系列》之九