122023.05

包拯断案 | 揭晓Linux下CPU利用率过高的谜底与方法@还故障一个真相

2023.05.12
提问:作为DBA运维的你是否有过这些苦恼

1)CPU高但没有慢SQL,该如何排查分析?
2)CPU剩余资源很多,但数据库性能很差,该如何分析?



图片



心中有章,遇事不慌

图片


作为DBA的你,遇到问题无从下手,除了在问题面前徘徊,还能如何选择?如果你一次或多次遇到该问题还是无法解决,又很懊恼,该如何排忧呢?关注公众号,关注《包拯断案》专栏,让小编为你排忧解难~


#包拯秘籍#

一整套故障排错及应对策略送给你,让你像包拯一样断案如神:

#首先

遇到此类问题后 我们要做到心中有章(章程),遇事不慌。一定要冷静,仔细了解故障现象(与研发/用户仔细沟通其反馈的问题,了解故障现象、操作流程、数据库架构等信息)

#其次

我们要根据故障现象进行初步分析。心中要想:什么情况会导致CPU升高?例如:因为大量慢SQL导致?CPU在等待io资源导致负载升高?还是CPU资源使用不均衡?

#然后

针对上述思考,我们需要逐步验证并排除,确定问题排查方向。

#接着

确定了问题方向,进行具体分析。通过现象得出部分结论,通过部分结论继续排查并论证。

#最后

针对问题有了具体分析后,再进行线下复现,最终梳理故障报告。



真刀实战,我们能赢

图片


说了这么多理论,想必实战更让你心动。那我们就拿一个真实案例进行分析---当应用连接数据库失败,导致业务受阻,该如何快速分析处理:


-2.1 故障处理场景

加班不是福报,工作效率高才是王道。突然而来的信息打破了正在划水的你……

什么!???

⚠️突然收到客户DBA发来的一条线上数据库实例报警信息:数据库进程的CPU使用率过高,经过初步排查,没有发现慢SQL,暂不知问题原因!


瞬间警醒,慌得一匹,数据库抽风了?并发大了?无数个【可能】从脑海中闪过……


1)使用top进行观察

top - 21:57:11 up 1 day, 10:15, 1 user, load   average: 12.04, 3.08, 1.06

Tasks: 155 total, 1 running, 154 sleeping, 0   stopped, 0 zombie

%Cpu(s): 31.7 us, 32.3 sy, 0.0 ni, 3.0 id, 8.3 wa,   0.0 hi, 24.8 si, 0.0 st

KiB Mem : 3879932 total, 146516 free, 3653848 used,   79568 buff/cache

KiB Swap: 8126460 total, 5448596 free, 2677864   used. 67272 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+   COMMAND

17243 mysql 20 0 5590880 3.2g 2992 S 327.6 85.8   13:29.50 mysqld

...

由上可知:

目前系统一分钟负载为12.04,且是递增趋势,说明系统目前的压力是陡增的,用户态CPU使用率为31.7%,内核态使用率为32.3%。出现了io等待情况,证明目前io压力也很大,且si比较高,证明CPU等待软中断完成的时间更长,也符合内核态的使用率高的现象。


2)使用ps查看进程端口号

[root@lh-2 ~]# ps -aux|grep 17243

root 5237 0.0 0.0 123144 1240 pts/0 S+ 22:00 0:00   grep --color=auto 17243

mysql 17243 1.2 87.0 5607264 3378152 ? Sl 1月11 20:02   ./mysqld --defaults-file=/data/3307/conf/my.cnf

由上可知:和top统计的信息类似


3)使用pidstat检查端口号和资源

[root@lh-2 data]# pidstat -u -p 17243 1 3

Linux 3.10.0-1160.45.1.el7.x86_64 (lh-2) 2022年01月13日 _x86_64_ (4 CPU)

16时38分00秒   UID PID %usr %system %guest %wait %CPU CPU Command

16时38分03秒   1000 17243 85.71 194.68 0.00 0.00 280.40 1 mysqld

16时38分06秒   1000 17243 78.60 184.95 0.00 0.00 263.55 1 mysqld

...

由上可知:目前cpu利用率高的是MySQL进程,且内核态比用户态多


4)查看哪个占用的io比较高

shell> top -H -p 17243

top - 16:57:27 up 6:25, 3 users, load average:   6.50, 4.57, 4.21

Threads: 52 total, 5 running, 47 sleeping, 0   stopped, 0 zombie

%Cpu(s): 19.0 us, 30.5 sy, 0.0 ni, 8.6 id, 17.2 wa,   0.0 hi, 24.7 si, 0.0 st

KiB Mem : 3879932 total, 115712 free, 3693012 used,   71208 buff/cache

KiB Swap: 8126460 total, 5736736 free, 2389724   used. 32876 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+   COMMAND

3111 mysql 20 0 5493272 3.3g 840 R 22.8 90.1   0:52.01 connection

3118 mysql 20 0 5493272 3.3g 840 S 22.8 90.1   0:52.57 connection

3106 mysql 20 0 5493272 3.3g 840 R 22.5 90.1   0:52.23 connection

由上可知:我们可以看到MySQL下占用CPU资源最多的是connection的几个线程


5)使用pidstat命令查看

shell> pidstat -u -t 1 5 -p 17243

平均时间: 1000 - 3106 7.55 16.10 0.00 35.79 23.66 -   |__connection

平均时间: 1000 - 3111 7.95 15.31 0.00 35.98 23.26 -   |__connection

平均时间: 1000 - 3118 6.76 17.30 0.00 38.17 24.06 -   |__connection

... ...

由上可知:我们可以看到MySQL下占用CPU资源最多的是connection的几个线程


6)使用perf top进行查看

shell> perf top -t 3106

Samples: 988K of event 'cpu-clock', 4000 Hz, Event   count (approx.): 84768870215 lost: 0/0 drop: 0/0

Overhead Shared Object Symbol

16.82% [kernel] [k] _raw_spin_unlock_irqrestore   16.75% [kernel] [k] __do_softirq 9.22% [kernel] [k] e1000_xmit_frame   5.73% [kernel] [k] e1000_clean 3.81% [kernel] [k] finish_task_switch 3.38%   mysqld [.] ut_delay 2.27% [kernel] [k] 

e1000_alloc_rx_buffers 1.63% mysqld   [.] ha_insert_for_fold_func 1.23% mysqld [.] 

ha_delete_hash_node 1.16% mysqld   [.] ha_remove_all_nodes_to_page


由上可知:

当前系统内核cpu使用率高的进程是_raw_spin_unlock_irqrestore,说明一直在发生软中断。


结论:

经过上述分析,当前cpu利用率升高的原因是系统内核占用的CPU资源比较多,造成原因是当前CPU发生频繁的上下文切换,也就是发生了软中断导致内核态的cpu利用率升高,而争抢cpu资源的线程是connection线程(连接线程)。该线程是MySQL进程的,因此该问题的根本原因是:当前有大量并发请求MySQL进程,导致资源不足出现争抢情况


图片


本期复盘总结
图片


1)本次故障主要是因为数据库接收了大量的并发请求,导致大量线程争抢CPU资源,Linux操作系统的频繁切换,导致系统调度繁忙,引起了CPU使用率增高

2)在低配的硬件下减少数据库连接数的创建
3)增加Linux CPU细粒度的监控(包含用户态和内核态的资源监控)
4)基于巡检项开发自动化运维脚本与告警相结合的方式,自动进行故障分析


图片
番外篇-展昭答疑解惑

1)如果CPU核数很大,在部分CPU资源没被利用上的情况下还是发生了CPU告警,该如何处理?


答:首先需要确定:数据库是否已经全部均匀使用了所有CPU(多核).如果没有,则需要排查一下数据库的numa node使用情况;如果使用不合理,出现CPU资源偏移(累得累死,闲得闲死),则需要考虑让数据库均匀使用物理资源。


2)遇到这类问题,该如何避免?


答:其一:使用numa来保证数据库能够均匀使用CPU、内存资源;其二:如果硬件太差,可以考虑升级硬件资源。