操作系统层面的 `vmstat`, `iostat`, `netstat` 输出与 MySQL 性能关联

好的,各位技术大佬、未来的架构师们,大家好!我是你们的老朋友,今天咱们不聊代码,咱们聊聊那些躲在操作系统背后的“侦察兵”—— vmstatiostatnetstat。别看它们的名字像科幻电影里的机器人,其实它们是监控系统资源利用率的利器,更是我们诊断 MySQL 性能问题的秘密武器!

想象一下,MySQL 数据库就像一个辛勤的厨师,负责烹饪美味的数据大餐。而操作系统就是这个厨房,CPU 是炉灶,内存是食材架,磁盘是储物柜,网络是传送带。如果厨房运作不畅,再好的厨师也做不出美味佳肴。所以,想要 MySQL 跑得飞快,就得先了解厨房的运作情况。

今天,我们就手把手教大家如何利用 vmstatiostatnetstat 这三个“侦察兵”,深入了解操作系统层面的性能瓶颈,从而更好地优化 MySQL 数据库。

第一章:侦察兵 vmstat – 内存与 CPU 的守护者

vmstat,全称 Virtual Memory Statistics,顾名思义,它主要关注虚拟内存的使用情况。但它提供的远不止内存信息,还包括 CPU 使用率、进程状态等关键数据。就像一个经验丰富的管家,它能告诉你:

  • “老爷(CPU)最近是不是很忙?”
  • “家里的食材(内存)够不够用?”
  • “有没有客人(进程)在排队等候?”

让我们先来召唤一下 vmstat

vmstat 1 5

这条命令的意思是:每隔 1 秒输出一次 vmstat 的报告,总共输出 5 次。输出结果大概是这个样子:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 2048000  10240 512000    0    0     2     1   10   5 10 1 10 78 0
 0  0      0 2048000  10240 512000    0    0     0     0   12   3 5 0 95 0 0
 0  0      0 2048000  10240 512000    0    0     0     0    8   2 2 0 98 0 0
 0  0      0 2048000  10240 512000    0    0     0     0   11   4 3 0 97 0 0
 0  0      0 2048000  10240 512000    0    0     0     0    9   3 2 0 98 0 0

是不是觉得有点眼花缭乱?别怕,我们来逐个解读:

含义 诊断意义
procs
r 运行队列中的进程数 (Runnable processes) 如果这个值长期大于 CPU 的核心数,说明 CPU 资源紧张,进程都在排队等待执行。你的 MySQL 厨师可能在抱怨:“炉灶不够用啊,客人们都饿着肚子呢!” 建议:考虑升级 CPU 或者优化 SQL 语句,减少 CPU 的消耗。
b 处于不可中断睡眠状态的进程数 (Blocked processes) 如果这个值持续较高,说明进程可能在等待 I/O 操作完成,比如等待磁盘读写。你的 MySQL 厨师可能在抱怨:“储物柜(磁盘)太慢了,我拿不到食材啊!” 建议:检查磁盘 I/O 是否成为瓶颈,可以考虑升级磁盘或者优化 I/O 相关的配置。
memory
swpd 使用的 swap 空间大小 (Used swap memory) 如果这个值不为零,说明系统正在使用 swap 空间。这意味着物理内存不足,部分数据被交换到磁盘上。你的 MySQL 厨师可能在抱怨:“食材架(内存)不够用了,我只能把一部分食材放到地下室(磁盘)里,拿起来太慢了!” 建议:增加物理内存,或者优化 MySQL 的内存使用,减少内存消耗。
free 空闲的物理内存大小 (Free memory) 这个值越小,说明系统剩余的内存越少。但是,不要仅仅看这个值,因为 Linux 系统会利用剩余内存作为 buffer 和 cache。
buff 用于 buffer 的内存大小 (Memory used as buffers) buffer 主要用于缓存磁盘的元数据,例如目录结构。
cache 用于 cache 的内存大小 (Memory used as cache) cache 主要用于缓存磁盘上的数据。如果 cache 的值很大,说明系统经常访问磁盘上的数据,这可以提高性能。
swap
si 每秒从磁盘读入 swap 的数据量 (Swap in) 如果这个值持续较高,说明系统频繁地进行 swap 操作,性能会急剧下降。你的 MySQL 厨师可能在抱怨:“我一直在地下室(磁盘)和厨房(内存)之间跑来跑去,累死了!” 建议:同 swpd 的建议。
so 每秒写入磁盘的 swap 数据量 (Swap out) 如果这个值持续较高,说明系统频繁地进行 swap 操作,性能会急剧下降。你的 MySQL 厨师可能在抱怨:“我一直在地下室(磁盘)和厨房(内存)之间跑来跑去,累死了!” 建议:同 swpd 的建议。
io
bi 每秒从块设备读取的数据量 (Blocks received) 这个值反映了磁盘的读取速度。
bo 每秒写入块设备的数据量 (Blocks sent) 这个值反映了磁盘的写入速度。如果 bibo 的值都很高,说明磁盘 I/O 压力很大。你的 MySQL 厨师可能在抱怨:“储物柜(磁盘)太慢了,我拿食材和放食材都慢!” 建议:检查磁盘 I/O 是否成为瓶颈,可以考虑升级磁盘或者优化 I/O 相关的配置。
system
in 每秒中断数 (Interrupts) 中断是硬件设备通知 CPU 的一种方式。如果这个值过高,说明系统被中断频繁打断,CPU 的效率会下降。
cs 每秒上下文切换数 (Context switches) 上下文切换是指 CPU 从一个进程切换到另一个进程。如果这个值过高,说明 CPU 频繁地进行进程切换,CPU 的效率会下降。你的 MySQL 厨师可能在抱怨:“客人(进程)太多了,我忙不过来,一会儿给这个做菜,一会儿给那个做菜,累死了!” 建议:优化 SQL 语句,减少进程的数量,或者增加 CPU 的核心数。
cpu
us 用户态 CPU 使用率 (User CPU time) 这个值反映了用户进程占用 CPU 的时间比例。如果这个值很高,说明用户进程消耗了大量的 CPU 资源。你的 MySQL 厨师可能在抱怨:“菜谱(SQL 语句)太复杂了,我得花很多时间才能做出来!” 建议:优化 SQL 语句,减少 CPU 的消耗。
sy 系统态 CPU 使用率 (System CPU time) 这个值反映了内核进程占用 CPU 的时间比例。如果这个值很高,说明内核进程消耗了大量的 CPU 资源。
id 空闲 CPU 使用率 (Idle CPU time) 这个值反映了 CPU 的空闲程度。如果这个值很低,说明 CPU 资源紧张。
wa 等待 I/O 的 CPU 使用率 (IO-wait CPU time) 这个值反映了 CPU 等待 I/O 操作完成的时间比例。如果这个值很高,说明 I/O 操作成为瓶颈。你的 MySQL 厨师可能在抱怨:“储物柜(磁盘)太慢了,我得等很久才能拿到食材!” 建议:检查磁盘 I/O 是否成为瓶颈,可以考虑升级磁盘或者优化 I/O 相关的配置。
st 被偷走的 CPU 使用率 (Steal CPU time) 这个值反映了 CPU 被其他虚拟机偷走的时间比例。这个值只有在虚拟机环境中才有意义。

第二章:侦察兵 iostat – 磁盘 I/O 的巡逻员

iostat,全称 Input/Output Statistics,专门负责监控磁盘 I/O 的性能。就像一个专业的巡逻员,它能告诉你:

  • “哪个储物柜(磁盘)最繁忙?”
  • “厨师(MySQL)从储物柜(磁盘)里拿食材的速度有多快?”
  • “储物柜(磁盘)是不是堵车了?”

让我们召唤一下 iostat

iostat -x 1 5

这条命令的意思是:每隔 1 秒输出一次 iostat 的详细报告,总共输出 5 次。-x 参数表示输出更详细的信息。输出结果大概是这个样子:

Linux 5.4.0-91-generic (ubuntu20)   09/29/2023  _x86_64_        (8 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.25    0.00    0.13    0.00    0.00   99.63

Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
sda               0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
sdb               0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
nvme0n1           0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00

同样,我们来逐个解读:

含义 诊断意义
Device 设备名称 例如 sdasdbnvme0n1 等,代表不同的磁盘设备。
r/s 每秒读取的请求数 (Reads per second) 如果这个值很高,说明磁盘的读取压力很大。
w/s 每秒写入的请求数 (Writes per second) 如果这个值很高,说明磁盘的写入压力很大。
rkB/s 每秒读取的 KB 数 (Kilobytes read per second) 这个值反映了磁盘的读取速度。
wkB/s 每秒写入的 KB 数 (Kilobytes written per second) 这个值反映了磁盘的写入速度。
rrqm/s 每秒合并的读取请求数 (Reads requests merged per second) 如果这个值很高,说明系统能够将多个小的读取请求合并成一个大的请求,这可以提高磁盘的读取效率。
wrqm/s 每秒合并的写入请求数 (Write requests merged per second) 如果这个值很高,说明系统能够将多个小的写入请求合并成一个大的请求,这可以提高磁盘的写入效率。
%rrqm 读取请求合并的百分比
%wrqm 写入请求合并的百分比
r_await 平均每次读取请求的等待时间 (Average read await time in milliseconds) 如果这个值很高,说明读取请求需要等待很长时间才能完成,磁盘的读取性能可能存在瓶颈。你的 MySQL 厨师可能在抱怨:“储物柜(磁盘)太慢了,我得等很久才能拿到食材!” 建议:检查磁盘 I/O 是否成为瓶颈,可以考虑升级磁盘或者优化 I/O 相关的配置。
w_await 平均每次写入请求的等待时间 (Average write await time in milliseconds) 如果这个值很高,说明写入请求需要等待很长时间才能完成,磁盘的写入性能可能存在瓶颈。你的 MySQL 厨师可能在抱怨:“储物柜(磁盘)太慢了,我得等很久才能把食材放进去!” 建议:检查磁盘 I/O 是否成为瓶颈,可以考虑升级磁盘或者优化 I/O 相关的配置。
aqu-sz 平均队列长度 (Average queue length) 这个值反映了等待 I/O 操作的请求队列的长度。如果这个值很高,说明磁盘 I/O 压力很大,有很多请求在排队等待。你的 MySQL 厨师可能在抱怨:“储物柜(磁盘)门口排了好多人,我根本拿不到食材!” 建议:检查磁盘 I/O 是否成为瓶颈,可以考虑升级磁盘或者优化 I/O 相关的配置。
rareq-sz 平均每次读取请求的大小 (Average read request size in kilobytes) 这个值反映了每次读取请求的数据量大小。
wareq-sz 平均每次写入请求的大小 (Average write request size in kilobytes) 这个值反映了每次写入请求的数据量大小。
svctm 平均每次 I/O 操作的服务时间 (Average service time in milliseconds) 这个值反映了磁盘处理 I/O 请求所需的时间。如果这个值很高,说明磁盘的性能可能存在瓶颈。
%util 磁盘利用率 (Disk utilization) 这个值反映了磁盘的繁忙程度。如果这个值接近 100%,说明磁盘已经饱和,I/O 操作可能会受到限制。你的 MySQL 厨师可能在抱怨:“储物柜(磁盘)一直在工作,根本停不下来!” 建议:检查磁盘 I/O 是否成为瓶颈,可以考虑升级磁盘或者优化 I/O 相关的配置。

第三章:侦察兵 netstat – 网络连接的监视者

netstat,全称 Network Statistics,专门负责监控网络连接的状态。就像一个网络巡逻员,它能告诉你:

  • “有多少客人(客户端)正在访问厨房(MySQL)?”
  • “厨房(MySQL)和客人(客户端)之间的传送带(网络)是不是畅通?”
  • “有没有可疑的客人(客户端)在偷偷摸摸地访问厨房(MySQL)?”

让我们召唤一下 netstat

netstat -nat | grep 3306

这条命令的意思是:列出所有的 TCP 连接,并过滤出端口号为 3306 的连接(MySQL 的默认端口号)。输出结果大概是这个样子:

tcp        0      0 127.0.0.1:3306          127.0.0.1:40000         ESTABLISHED
tcp        0      0 127.0.0.1:3306          127.0.0.1:40001         ESTABLISHED

我们来解读一下:

含义 诊断意义
Proto 协议类型 通常是 tcpudp
Recv-Q 接收队列的长度 (Receive queue length) 如果这个值持续较高,说明接收队列满了,数据包可能会被丢弃。你的 MySQL 厨师可能在抱怨:“传送带(网络)太慢了,我收不到客人们的订单!” 建议:检查网络带宽是否足够,或者优化网络相关的配置。
Send-Q 发送队列的长度 (Send queue length) 如果这个值持续较高,说明发送队列满了,数据包可能会被丢弃。你的 MySQL 厨师可能在抱怨:“传送带(网络)太堵了,我送不出去菜!” 建议:检查网络带宽是否足够,或者优化网络相关的配置。
Local Address 本地地址和端口号 (Local address and port) 例如 127.0.0.1:3306,表示 MySQL 数据库监听的地址和端口号。
Foreign Address 远程地址和端口号 (Foreign address and port) 例如 127.0.0.1:40000,表示客户端连接的地址和端口号。
State 连接状态 (Connection state) 例如 ESTABLISHED,表示连接已经建立。其他常见的状态包括 LISTEN(监听)、SYN_SENT(正在发送 SYN 包)、SYN_RECEIVED(收到 SYN 包)、CLOSE_WAIT(等待关闭)、TIME_WAIT(等待超时)等。如果出现大量的 TIME_WAIT 连接,可能会消耗大量的系统资源。你的 MySQL 厨师可能在抱怨:“客人们吃完饭就赖着不走,占着位置!” 建议:优化 TCP 连接相关的配置,例如缩短 TIME_WAIT 的超时时间。

除了上面这些,netstat 还可以用于查看网络接口的统计信息,例如:

netstat -i

这个命令会列出所有网络接口的统计信息,包括接收和发送的数据包数量、错误数量等。这些信息可以帮助你诊断网络接口的性能瓶颈。

第四章:综合分析与案例实战

光了解这些“侦察兵”的用法还不够,更重要的是要学会综合分析它们提供的信息,才能真正找到 MySQL 性能瓶颈的根源。

案例一:CPU 瓶颈

假设我们运行 vmstat 命令,发现 us 列的值持续较高,而 id 列的值持续较低,这说明 CPU 资源紧张。接下来,我们可以使用 top 命令或者 MySQL 的 SHOW PROCESSLIST 命令,查看哪些进程或 SQL 语句消耗了大量的 CPU 资源。

优化方向:

  • 优化 SQL 语句,减少 CPU 的消耗。
  • 增加 CPU 的核心数。
  • 使用缓存技术,减少数据库的访问次数。

案例二:内存瓶颈

假设我们运行 vmstat 命令,发现 swpd 列的值不为零,并且 siso 列的值持续较高,这说明系统正在使用 swap 空间,物理内存不足。

优化方向:

  • 增加物理内存。
  • 优化 MySQL 的内存使用,减少内存消耗。
  • 调整 MySQL 的配置参数,例如 innodb_buffer_pool_size,使其更合理地利用内存。

案例三:磁盘 I/O 瓶颈

假设我们运行 iostat 命令,发现某个磁盘的 %util 列的值接近 100%,并且 r_awaitw_await 列的值很高,这说明磁盘 I/O 已经饱和。

优化方向:

  • 升级磁盘,例如使用 SSD 替代 HDD。
  • 优化 I/O 相关的配置,例如调整 innodb_flush_method 参数。
  • 使用 RAID 技术,提高磁盘的 I/O 性能。
  • 将 MySQL 的数据文件和日志文件分散到不同的磁盘上,减少 I/O 冲突。

案例四:网络瓶颈

假设我们运行 netstat 命令,发现大量的 TIME_WAIT 连接,或者 Recv-QSend-Q 列的值持续较高,这说明网络可能存在瓶颈。

优化方向:

  • 优化 TCP 连接相关的配置,例如缩短 TIME_WAIT 的超时时间。
  • 增加网络带宽。
  • 使用连接池技术,减少 TCP 连接的建立和关闭次数。
  • 检查网络设备(例如交换机、路由器)的性能。

总结:

vmstatiostatnetstat 就像三位经验丰富的“侦察兵”,它们默默地守护着我们的系统,为我们提供了宝贵的性能信息。学会利用它们,我们就能更好地了解系统的运作情况,及时发现并解决性能瓶颈,让 MySQL 数据库跑得更快、更稳!

希望今天的分享对大家有所帮助。记住,技术之路漫漫,唯有不断学习和实践,才能成为真正的技术专家! 祝大家编码愉快,bug 远离! 😄

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注