code学习

【StoneDB故障诊断】系统资源瓶颈诊断

当操作系统的资源出现瓶颈时,不仅操作系统上的应用服务受到影响,而且在操作系统执行简单的命令可能都无法返回结果。在操作系统尚未完全夯死前,可以使用相关命令对CPU、内存、IO和网络资源的使用情况进行信息的收集,然后分析确认这些资源是否被合理利用,是否存在瓶颈。

CPU

top、vmstat都可以检查CPU的使用情况,但top的结果显示的更全面。top返回的结果有两层,上层是系统性能的统计信息,下层是进程的统计信息,默认按照CPU的使用率排序。

top返回结果示例如下:

top - 10:12:21 up 5 days, 22:31,  4 users,  load average: 1.00, 1.00, 0.78
Tasks: 731 total,   1 running, 730 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.7 us,  0.0 sy,  0.0 ni, 98.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem : 257841.3 total,   1887.5 free,  45581.6 used, 210372.2 buff/cache
MiB Swap:   8192.0 total,   8188.7 free,      3.3 used. 210450.4 avail Mem 

PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                
908076 mysql     20   0  193.0g  42.4g  44088 S 100.3  16.8 228:10.34 mysqld                                                                                                                 
823137 root      20   0 6187564  83772  51636 S   6.6   0.0   6:36.12 dockerd                                                                                                                
822938 root      20   0 3278696  58500  35420 S   0.7   0.0  38:37.69 containerd                                                                                                             
1483 root      20   0  239280   9260   8136 S   0.3   0.0   0:19.16 accounts-daemon                                                                                                        
928343 root      20   0    9936   4576   3240 R   0.3   0.0   0:00.04 top                                                                                                                    
  ......      

第一行

10:12:21:当前系统时间

up 5 days:自上一次系统启动后到现在的运行天数

4 user:登录到系统的用户数

load average:过去1分钟、5分钟、15分钟,系统负载的平均值

第二行

total:系统进程总数

running:处于运行状态的进程数

sleeping:处于休眠状态的进程数

stopped:处于被停止状态的进程数

zombie:处于僵尸状态进程数

第三行

us:用户进程占用CPU的百分比

sy:系统进程占用CPU的百分比

ni:优先级被改变过的进程占用CPU的百分比

id:空闲CPU占用的百分比

wa:IO等待占用CPU的百分比

hi:硬件中断占用CPU的百分比

si:软件中断占用CPU的百分比

st:虚拟化环境占用CPU的百分比

需要重点关注CPU的使用率,当us值较高时,说明用户进程消耗CPU时间较多,如果长时间超过50%时,应尽快优化应用服务。当sy值较高时,说明系统进程消耗CPU时间较多,比如可能是操作系统配置不合理或者出现操作系统的Bug。当wa值较高时,说明系统IO等待比较严重,比如可能是发生了大量的随机IO访问,IO带宽出现瓶颈。

第四行

total:物理内存总大小,单位为M

free:空闲的内存大小

used:已使用的内存大小

buff/cache:已缓存的内存大小

第五行

total:Swap大小

free:空闲的Swap大小

used:已使用的Swap大小

avail Mem:已缓存的Swap大小

进程列表

PID:进程的id

USER:进程的拥有者

PR:进程的优先级,值越小越优先执行

NI:进程nice值,正值表示降低进程优先级,负值表示提高进程优先级,nice取值范围为(-20,19),默认情况下,进程的nice值为0

VIRT:进程占用的虚拟内存大小

RES:进程占用的物理内存大小

SHR:进程占用的共享内存大小

S:进程状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数

%CPU:进程CPU使用率

%MEM:进程内存使用率

TIME+:进程启动后占用CPU的总时间,即占用CPU使用时间的累加值

COMMAND:进程启动命令名称

出现CPU使用率高诊断方法:

1)找出调用的函数

top -H
perf top -p xxx      

注:xxx为top -H返回最消耗CPU的进程。

2)找出消耗CPU的SQL

pidstat -t -p <mysqld_pid> 1 5
select * from performance_schema.threads where thread_os_id = xxx\G
select * from information_schema.processlist where id = performance_schema.threads.processlist_id\G      

注:xxx为pidstat返回最消耗CPU的线程。

内存

top、vmstat、free都可以检查内存的使用情况。

free返回结果示例如下:

# free -g
total        used        free      shared  buff/cache   available
Mem:            251          44           1           0         205         205
Swap:             7           0           7      

total:物理内存总大小,total = used + free + buff/cache

used:已使用的内存大小

free:空闲的内存大小

shared:共享内存大小

buff/cache:缓存内存大小

available:可用物理内存大小,available = free + buff/cache

出现内存使用率高诊断方法:

1)检查配置是否合理,例如:操作系统物理内存128G,而分配给数据库实例110G,由于操作系统进程和其它应用程序也需要内存,很容易导致内存被消耗光;

2)检查并发连接数是否过高,read_buffer_size、read_rnd_buffer_size、sort_buffer_size、thread_stack、join_buffer_size、binlog_cache_size都是session级别的,连接数越多,需要的内存就越多,因此这些参数也不能设置太大;

3)检查是否有不合理的join,例如:多表关联时,执行计划中驱动表的结果集比较大,需要循环多次执行,容易导致内存泄漏;

4)检查打开文件数是否过多和table_open_cache是否设置合理,访问一个表时,会将该表放入缓存区table_open_cache,目的是下次可以更快的访问,但如果table_open_cache设置太大,且打开的表又多的情况下,是很消耗内存的。

IO

iostat、dstat、pidstat都可以检查IO的使用情况。

iostat返回结果示例如下:

# iostat -x 1 1
Linux 3.10.0-957.el7.x86_64 (htap2)     06/13/2022      _x86_64_        (64 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
0.06    0.00    0.03    0.01    0.00   99.90

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     0.00    0.00    0.00     0.04     0.00    85.75     0.00    0.25    0.25    0.00   0.15   0.00
sdb               0.06     0.11    7.61    1.10  1849.41    50.81   436.48     0.36   40.93   46.75    0.48   1.56   1.35
dm-0              0.00     0.00    0.28    0.19     8.25    12.05    87.01     0.00    4.81    7.37    0.94   1.61   0.08      

rrqm/s: 每秒进行merge的读操作数

wrqm/s: 每秒进行merge的写操作数

r/s:每秒读IO次数

w/s:每秒写IO次数

rkB/s:每秒读IO大小,单位为KB

wkB/s:每秒写IO大小,单位为KB

avgrq-sz:平均请求大小,单位为扇区(512B)

avgqu-sz:在驱动请求队列和在设备中活跃的平均请求数

await:平均IO响应时间,包括在驱动请求队列里的等待和设备的IO响应时间

r_await:每次读操作IO响应时间

w_await:每次写操作IO响应时间

svctm:磁盘设备的IO平均响应时间

%util:设备忙处理IO请求的百分比(使用率),磁盘的繁忙程度

r/s + w/s:IOPS

出现IO使用率高诊断方法:

1)找出使用率最高的磁盘设备

iostat -x -m 1
iostat -d /dev/sda -x -m 1      

2)找出占用IO高的应用程序

pidstat -d 1      

3)找出占用IO高的线程

pidstat -dt -p mysqld_id 1      
select * from performance_schema.threads where thread_os_id = xxx\G
select * from information_schema.processlist where id = performance_schema.threads.processlist_id\G