操作系统级别 IO 性能


# iostat -xm 1
Linux 3.10.0-229.el7.x86_64 (demo.example.com)     11/04/2019     _x86_64_    (1 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.44    0.00    0.48    0.31    0.00   98.76

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.19     0.47    2.38    0.61     0.08     0.01    62.85     0.09   31.47   37.77    6.71   1.83   0.55
sdb               0.00     0.00    0.00    0.00     0.00     0.00     8.06     0.00    0.08    0.08    0.00   0.08   0.00
dm-0              0.00     0.00    0.19    0.45     0.00     0.00     8.00     0.07  102.24    7.55  142.81   0.63   0.04
dm-1              0.00     0.00    2.33    0.59     0.08     0.01    62.39     0.09   32.12   38.68    6.04   1.84   0.54


在上面的例子中,有两块硬盘 sda, sdb,sda 上有两个分区 sda1(用于 /boot) 和 sda2(用作PV)。dm-0 和 dm-1 是 swap 和 / 对应的 LV。

指标说明
%user:CPU处在用户模式下的时间百分比
%nice:CPU处在带NICE值的用户模式下的时间百分比
%system:CPU处在系统模式下的时间百分比
%iowait:CPU等待IO完成时间的百分比,如果该值过高,表示硬盘存在I/O瓶颈
%steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意的等待时间的百分比
%idle:闲置cpu的百分比,如果该值高,表示CPU较空闲,如果该值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量
rrqm/s:每秒进行 merge 的读操作数目
wrqm/s:每秒进行 merge 的写操作数目
r/s:每秒完成的合并后的读 I/O 设备次数, r/s+w/s 就是实际的 IOPS
w/s:每秒完成的合并后的写 I/O 设备次数, r/s+w/s 就是实际的 IOPS
rsec/s:每秒读扇区数
wsec/s:每秒写扇区数
rkB/s:每秒读K字节数
wkB/s:每秒写K字节数
avgrq-sz:平均每次设备I/O操作的数据大小 (扇区)
avgqu-sz:平均I/O队列长度,如果avgqu-sz比较大,也表示有大量io在等待(HDD可能在4左右,SSD可以达到30左右)
await:平均每次设备I/O操作的等待时间 (毫秒),如果 await 远大于 svctm,说明I/O队列太长,io响应太慢,则需要进行必要优化
svctm:平均每次设备I/O操作的服务时间 (毫秒),如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间,MAN 文档中说不要相信这个值
%util:一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比。如果 %util 接近 100%,说明产生的I/O请求太多,磁盘很繁忙。如果该值100% 不能简单的等同于磁盘的负载满了,达到了瓶颈◦ 需要综合 avgqu-sz 、 await 等其他指标进行综合判断磁盘是否达到瓶颈。例如,尽管100%了,但是 IOPS,avgqu-sz并没有用尽,则并没有达到瓶颈

查看 MySQL 的 IO 情况

# iotop -u mysql

这个命令能看到 MySQL 的内部各线程号及其 IO 情况,如果想知道这些线程号具体对应什么线程名,可以通过 performance_schema.threads 表来查看线程与进程的对应关系:

mysql> select name,type,thread_id,thread_os_id,processlist_id from performance_schema.threads;

其中,srv_master_thread 行就是主线程,one_connection 为前台线程,processlist_id 可以通过 show processlist 或者 select connection_id() 查看。

注意:MySQL 5.6 版本中没有 thread_os_id 这个列。我们通过 iotop 命令找到繁忙的 mysql 线程号后,并不能通过threads表知道是什么线程在忙。我们可以通过 gdb 来帮忙。

# gdb -ex "set pagination 0" -ex "thread apply all bt" --batch -p <mysqld进程号>

这样就会打印出mysqld进程的所有线程号以及各线程正在做的事情,这样,我们就可以推断出线程号对应的线程名了。

-- By 许望(RHCA、OCM、VCP)
最后修改:2019 年 11 月 06 日 11 : 22 AM
如果觉得我的文章对你有用,请随意赞赏