MySQL 调优基础(四) Linux 磁盘IO
1. IO处理过程
磁盘IO经常会成为系统的一个瓶颈,特别是对于运行数据库的系统而言。数据从磁盘读取到内存,在到CPU缓存和寄存器,然后进行处理,最后写回磁盘,中间要经过很多的过程,下图是一个以write为例的 Linux 磁盘IO子系统的架构:
可以看到IO操作分成了四个层面:
1)文件系统缓存:处理数据必须先从磁盘读到缓存,然后修改,然后刷会磁盘。缓存的刷新涉及到两个参数:vm.dirty_background_ratio、vm.dirty_ratio。还有刷新写回时,使用到 bio 结构,bio的组成是由磁盘上相邻的block组成的,所以这里进行了优化。
2)block layer:该层就涉及到 IO调度算法,IO调度算法在mysql服务器是一个很重要的调优手段。系统中所有进程申请的IO操作,全部在这里进行排队,等待调度,然后写回磁盘。调度算法有四种:
1> Anticipatory: 适用于个人PC,单磁盘系统;
2> CFQ(Complete Fair Queuing):默认的IO调度算法,完全公平的排队调度算法。每一个进程的IO请求会安排进一个专门的IO队列,然后按照进程组来公平的调度IO,也就是每一个进程组之间按照公平的方式来调度IO。显然他适合多用户的系统,但是极为不适合作为数据库系统的IO调度算法,因为显而易见,数据库系统中,数据库进程肯定是IO最多的一个进程组,然后它却只能获得和其它进程一样多的IO调度机会。所以显然这是极为不合理的。数据库系统绝对不要使用该调度算法。
3> Deadline: 按照截止期限来循环在各个IO队列中进行调度,所以它提供了一个近实时的IO系统,并且磁盘throughput也很好,也不会造成starvation.一般mysql系统建议采用该调度算法。
4> NOOP: 简单的FIFO队列进行调度,No operation的意思是,它没有进行额外的将临近的IO进行合并的操作,所以它对CPU的使用极少。该调度算法特别适合于SSD。因为SSD在对待顺序IO和随机IO没有什么区别。所以它不需要对临近的IO进行合并。避免了合并操作对CPU的使用。
所以一般而言,对于mysql的系统,如果是SSD,那么应该使用NOOP调度算法,如果是磁盘,就应该使用Deadline调度算法。
查看与修改IO调度算法:
临时修改:
- [root@localhost ~]# cat /sys/block/sda/queue/scheduler
- noop anticipatory deadline [cfq]
- [root@localhost ~]# echo noop > /sys/block/sda/queue/scheduler
- [root@localhost ~]# cat /sys/block/sda/queue/scheduler
- [noop] anticipatory deadline cfq
永久修改:
# vi /boot/grub/menu.lst
更改到如下内容:
kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet
重启之后,查看调度方法:
# cat /sys/block/sda/queue/scheduler
noop anticipatory [deadline] cfq
已经是deadline了
3)磁盘驱动层:对于顺序读系统而言,很容易在磁盘接口层的带宽上成为瓶颈所在;
4)磁盘:对于随机读多的系统而言,磁盘很容易成为瓶颈所在,一般的优化就是使用RAID或者换SSD;
2. IO瓶颈检测
2.1 使用 iostat 查看磁盘IO
显示单位问题:默认iostat是以磁盘的block为单位,也可以使用 -k 来指定以 kilobytes 为单位,或者使用 -m 指定 megabytes 为单位;
统计开始时间问题:默认iostat和vmstat相似,默认第一次/行都是从开机到目前的一个数据,可以使用 -y 选项去掉第一次/行的数据;
CPU与磁盘: iostat 默认会显示cpu和磁盘的数据,如果只要cpu数据可以使用 -c 选项,如果只需要磁盘数据,可以使用 -d 选项;
时间间隔和重复次数:[interval [times]] 表示磁盘统计数据的间隔时间和次数;
-x : 该选项显示具体的扩展信息;
- [root@localhost ~]# iostat
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- avg-cpu: %user %nice %system %iowait %steal %idle
- 0.60 0.00 7.80 0.31 0.00 91.30
- Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
- scd0 0.02 0.21 0.00
- sda 2.00 78.60 8.43 [root@localhost ~]# iostat -c
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- avg-cpu: %user %nice %system %iowait %steal %idle
- 0.48 0.00 6.51 0.25 0.00 92.76
- [root@localhost ~]# iostat -d -k
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
- scd0 0.02 0.08 0.00
- sda 1.69 31.17 4.15
- [root@localhost ~]# iostat -d -m
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
- scd0 0.02 0.00 0.00
- sda 1.69 0.03 0.00
- [root@localhost ~]# iostat -d -m -x
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
- scd0 0.02 0.00 0.02 0.00 0.00 0.00 10.94 0.00 4.96 4.88 0.01
- sda 1.22 0.48 1.13 0.56 0.03 0.00 41.66 0.01 6.83 5.27 0.89
- [root@localhost ~]# iostat -d -m -x 2 3
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
- scd0 0.02 0.00 0.01 0.00 0.00 0.00 10.94 0.00 4.96 4.88 0.01
- sda 1.19 0.48 1.10 0.55 0.03 0.00 41.52 0.01 6.81 5.25 0.87
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
- scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
- scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda 0.00 0.00 0.00 0.51 0.00 0.00 8.00 0.00 3.00 3.00 0.15
- [root@localhost ~]# iostat -y -d -m -x 2 3
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
- scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
- scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
- scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
字段含义:
Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn 分别表示:每秒读取block的个数,每秒写block的个数,总共读了多少个block,总共写了多少个block
tps: Indicate the number of transfers per second that were issued to the device. A transfer is an I/O request to the device. Multiple logical requests can be combined into a single I/O request to the device. A transfer is of indeterminate size.(就是对磁盘每秒请求多少次IO操作)
rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
rrqm/s wrqm/s 表示的磁盘读和写时每秒发生多少次相邻磁盘的merge操作;rrqm: read request merge; wrqm:write request merge
r/s w/s 表示每秒读的次数,写的次数;
rMB/s wMB/s 表示每秒读多少MB,写多少MB
avgrq-sz:The average size (in sectors) of the requests that were issued to the device. 平均一个IO请求涉及到多少个sector
avgqu-sz:The average queue length of the requests that were issued to the device. IO队列的平均长度,该数值很重要。
await:The average time (in milliseconds) for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.平均每一个IO花费了多少毫秒(包括在IO队列中的排队时间和读写操作花费的时间)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。
svctm:弃用
%util :Percentage of CPU time during which I/O requests were issued to the device (bandwidth utilization for the device). Device saturation occurs when this value is close to 100%. 在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备 的%util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度。一般地,如果该参数是100%表示设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因 为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。
CPU的 %iowait io等待很高;
磁盘的 avgqu-sz数值很大;await数值很高;%util数值很高;都可能预示着磁盘存在瓶颈或者磁盘出现问题或者故障。
2.2 使用 iostat 查看磁盘每个分区的IO
上面查看的都是整个磁盘的IO情况,下面的命令可以查看具体某个磁盘的所有分区的IO情况:
- [root@localhost ~]# iostat -x -d -m -p sda 2 3
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
- sda 0.82 0.43 0.76 0.52 0.02 0.00 38.49 0.01 6.27 4.82 0.62
- sda1 0.80 0.42 0.53 0.51 0.02 0.00 45.09 0.01 6.92 5.50 0.57
- sda2 0.01 0.02 0.12 0.01 0.00 0.00 9.70 0.00 2.95 2.79 0.04
- sda3 0.01 0.00 0.07 0.00 0.00 0.00 8.67 0.00 3.72 3.65 0.03
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await 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
- sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await 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
- sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- sda3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
- [root@localhost ~]# iostat -d -m -p sda 2 3
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
- sda 1.25 0.02 0.00
- sda1 1.02 0.02 0.00
- sda2 0.13 0.00 0.00
- sda3 0.07 0.00 0.00
- Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
- sda 0.00 0.00 0.00
- sda1 0.00 0.00 0.00
- sda2 0.00 0.00 0.00
- sda3 0.00 0.00 0.00
- Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
- sda 0.00 0.00 0.00
- sda1 0.00 0.00 0.00
- sda2 0.00 0.00 0.00
- sda3 0.00 0.00 0.00
2.3 使用 vmstat 查看磁盘IO
- [root@localhost ~]# vmstat 2 4
- procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
- r b swpd free buff cache si so bi bo in cs us sy id wa st
bi: Blocks received from a block device (blocks/s). 每秒读取多少个block到内存
bo: Blocks sent to a block device (blocks/s). 每秒内存写出多少个block到磁盘
2.4 使用 sar -b 查看磁盘IO
- [root@localhost ~]# sar -b 2 4
- Linux 2.6.-.el6.i686 (localhost.localdomain) // _i686_ ( CPU)
- :: PM tps rtps wtps bread/s bwrtn/s
- :: PM 0.00 0.00 0.00 0.00 0.00
- :: PM 0.00 0.00 0.00 0.00 0.00
- :: PM 0.00 0.00 0.00 0.00 0.00
- :: PM 0.00 0.00 0.00 0.00 0.00
- Average: 0.00 0.00 0.00 0.00 0.00
tps: 上面有介绍;rtps: 表示读的tps;wtps: 表示写的tps;
bread/s: 每秒读多少个block;bwrtn/s: 每秒写多少个block;
2.5 使用 iotop 找到IO最多的进程/线程
iotop类似于top命令,默认按照IO排序:
iotop :
iotop 是可以交互的:
Use the left and right arrows to change the sorting, r to reverse the sorting order, o to toggle the --only
option, p to toggle the --processes option, a to toggle the --accumulated option, q to quit or i to change the
priority of a thread or a process’ thread(s). Any other key will force a refresh.
1)利用左右键 可以选择排序的字段,默认按照IO>倒序,可以按照SWAPIN,DISK WRITE 等等字段排序,使用左右方向键即可;
2)利用 p键 可以在按照 进程显示 和按照 线程显示之间切换;
3)r 键可以改变排序的方向:倒序 和 顺序
查看mysqld的IO:
iotop -k -u mysql (-k 表示KB,-u mysql表示显示mysql用户的所有进程的IO):
3. 实例分析
- $$iostat -d -k 1 |grep sda10
- Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
- sda10 60.72 18.95 71.53 395637647 1493241908
- sda10 299.02 4266.67 129.41 4352 132
- sda10 483.84 4589.90 4117.17 4544 4076
- sda10 218.00 3360.00 100.00 3360 100
- sda10 546.00 8784.00 124.00 8784 124
- sda10 827.00 13232.00 136.00 13232 136
上面看到,磁盘每秒传输次数平均约400;每秒磁盘读取约5MB,写入约1MB。
- iostat -d -x -k 1
- Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
- sda 1.56 28.31 7.84 31.50 43.65 3.16 21.82 1.58 1.19 0.03 0.80 2.61 10.29
- sda 1.98 24.75 419.80 6.93 13465.35 253.47 6732.67 126.73 32.15 2.00 4.70 2.00 85.25
- sda 3.06 41.84 444.90 54.08 14204.08 2048.98 7102.04 1024.49 32.57 2.10 4.21 1.85 92.24
可以看到磁盘的平均响应时间<5ms,磁盘使用率>80。磁盘响应正常,但是已经很繁忙了。
4. 磁盘IO优化
磁盘IO在优化之前,首先要弄清楚系统的IO情况,是随机IO多,还是顺序IO多,是大文件IO多,还是小文件IO多(小文件IO一般也就是随机IO)。比如随机IO多,那么就可以通过加磁盘使用RAID技术来优化,如果是顺序IO遇到瓶颈,一般可能是磁盘驱动的带宽有瓶颈,就可以换一个更快的disk controller。搞清楚是磁盘有瓶颈,还是磁盘驱动的带宽有瓶颈。
因为磁盘IO的操作分成了4个层面,所以IO的优化也可以从这四个方面入手:
1)正对mysql系统的调优,还需要选择正确的IO调度算法,如果是SSD,选择NOOP调度算法,如果是磁盘,那么选择deadline调度算法;
2)针对mysql还显然可以通过master-slave来读写分离进行磁盘IO优化,如果没有master-slave架构,那么可以在前端加上memcache/redis缓存。
3)对于写很多造成的压力,则可以适当的采用Nosql(redis/mongdb/ssdb)等将可以分离出去的尽量分离出去。
4)另外增大内存,可以对更多的磁盘文件进行缓存,也能减轻IO压力。
5)还有文件系统的挂载选项 noatime, nodiratime也能减轻IO压力,另外选择正确的文件系统也能提高磁盘的tps. mysql数据库推荐使用XFS文件系统。
注:上面显示的磁盘IO的数据,很多都是0,这是因为数据来自于虚拟机中的Linux系统。
MySQL 调优基础(四) Linux 磁盘IO的更多相关文章
- MySQL 调优基础(五) Linux网络
1. TCP/IP模型 我们一般知道OSI的网络参考模型是分为7层:“应表会传网数物”——应用层,表示层,会话层,传输层,网络层,数据链路层,物理层.而实际的Linux网络层协议是参照了OSI标准,但 ...
- MySQL 调优基础(二) Linux内存管理
进程的运行,必须使用内存.下图是Linux中进程中的内存的分布图: 其中最重要的 heap segment 和 stack segment.其它内存段基本是大小固定的.注意stack是向低地址增长的, ...
- MySQL 调优基础:Linux内存管理 Linux文件系统 Linux 磁盘IO Linux网络
http://www.cnblogs.com/digdeep/category/739915.html
- MySQL 调优基础(三) Linux文件系统
Linux的文件系统有点像MySQL的存储引擎,它支持各种各样的文件系统.它最上层是通过 virtual files system虚拟文件系统作为一个抽象接口层来对外提供调用的.然后下层的各种文件系统 ...
- MySQL 调优基础(一) CPU与进程
一般而言,MySQL 的调优可以分为两个层面,一个是在MySQL层面上进行的调优,比如SQL改写,索引的添加,MySQL各种参数的配置:另一个层面是从操作系统的层面和硬件的层面来进行调优.操作系统的层 ...
- mysql调优 基础
MySQL调优可以从几个方面来做: 1. 架构层:做从库,实现读写分离: 2.系统层次:增加内存:给磁盘做raid0或者raid5以增加磁盘的读写速度:可以重新挂载磁盘,并加上noatime参数,这样 ...
- MySQL调优基础, 与hikari数据库连接池配合
1.根据硬件配置系统参数 wait_timeout 非交互连接的最大存活时间, 10-30min max_connections 全局最大连接数 默认100 根据情况调整 back_log ...
- 语句调优基础知识-set statistics io on
set statistics io on --清空缓存数据 dbcc dropcleanbuffers go --清空缓存计划 dbcc freeproccache go set statistics ...
- MySQL调优系列基础篇
前言 有一段时间没有写博客了,整天都在忙,上班,录制课程,恰巧最近一段时间比较清闲,打算弄弄MYSQL数据库. 关于MySQL数据库,这里就不做过多的介绍,开源.免费等特性深受各个互联网行业喜爱,尤其 ...
随机推荐
- 互联网背景时代下的大机遇,为什么用nosql
1.单机MySQL的美好年代 在90年代,一个网站的访问量一般都不大,用单个数据库完全可以轻松应付.在那个时候,更多的都是静态网页,动态交互类型的网站不多. 上述架构下,我们来看看数据存储的瓶颈是什么 ...
- java servlet调用带有多个返回结果集的存储过程
一.mysql存储过程 这里我先说下我这个功能实现的逻辑及途中遇到的一些问题.这个存储过程一共带两个输入参数,一共关联到两张表的查询,每个参数都对应查询表中的一个判断,所以一共返回了两个结果集(当然要 ...
- Java--concurrent并发包下阻塞队列介绍
JDK提供了7中阻塞队列,这里介绍其中3中,剩余的以此类推原理相同. 1.ArrayBlockingQueue package com.seeyon.queue; import java.util.c ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 利用Canvas编辑图片
使用<canvas>对象在浏览器中把一幅彩色图片变成灰度图片. grayscale.html <!DOCTYPE html> <html lang="en&qu ...
- ahjesus Ubuntu配置svn服务器
转载自http://www.cnblogs.com/ximu/articles/2119136.html 亲测可用 一.SVN安装1.安装包$ sudo apt-get install subvers ...
- nginx的pass_proxy遇到的坑
Pass_proxy走内网,被请求方的php使用remote_addr得到就是转发机器的内网地址,如192.168.10.141这样的.走外网,被请求方php的remote_addr得到就是转发机器的 ...
- Linux下安装DB2_v9.7详细教程
一:平台 1:HP服务器 cpu:Inter (R) Xeon (R) E5606 2.13G 磁盘:本地磁盘外加存储 2:操作系统 RedHet 5.4 64位 内核:2.6.18-194.1.AX ...
- 网上图书商城2--Category模块
sql CREATE TABLE `t_category` ( `cid` char(32) NOT NULL, `cname` varchar(50) DEFAULT NULL, `pid` cha ...
- GJM : Unity3D 常用网络框架与实战解析 【笔记】
Unity常用网络框架与实战解析 1.Http协议 Http协议 存在TCP 之上 有时候 TLS\SSL 之上 默认端口80 https 默认端口 ...