MySQL学习笔记(Day019:磁盘测试)
@(MySQL学习)
[TOC]
一. 磁盘调度算法介绍
1. CFQ
CFQ把I/O请求
按照进程
分别放入进程对应的队列中,所以A进程和B进程发出的I/O请求会在两个队列中。而各个队列内部仍然采用合并和排序
的方法,区别仅在于,每一个提交I/O请求的进程都有自己的I/O队列。
CFQ的“公平”是针对进程而言的,它以时间片算法为前提,轮转调度队列,默认从当前队列中取4个请求处理,然后处理下一个队列的4个请求。这样就可以确保每个进程享有的I/O资源是均衡的。
CFQ的缺点是先来的IO请求不一定能被及时满足,可能出现饥饿
的情况。
CFQ Wiki
2. Deadline
同CFQ一样,除了维护一个拥有合并和排序功能的请求队列以外,还额外维护了两个队列,分别是
读请求队列
和写请求队列
,它们都是带有超时的FIFO队列
。当新来一个I/O请求时,会被同时插入普通队列和读/写队列,然后处理普通队列中的请求。当调度器发现读/写请求队列中的请求超时的时候,会优先处理这些请求,保证尽可能不产生请求饥饿
在DeadLine算法中,每个I/O请求都有一个超时时间,默认读请求是500ms
,写请求是5s
。
Deadline Wiki
3. Noop
Noop做的事情非常简单,它不会对I/O请求排序也不会进行任何其它优化(除了合并)。Noop除了对请求合并以外,不再进行任何处理,直接以类似FIFO的顺序提交I/O请求。
Noop面向的不是普通的块设备,而是随机访问设备(例如SSD),对于这种设备,不存在传统的寻道时间,那么就没有必要去做那些多余的为了减少寻道时间而采取的事情了。
Noop Wiki
二. iostat(下)
rrqm/s 和 wrqm/s
Merge
将若干个连续地址的IO请求进行合并。来提高IO的效率rrqm/s
是每秒读(read)请求合并的次数wrqm/s
是每秒写(write)请求合并的次数
r/s和w/s
- 在
合并之后(after merge)
IO请求的次数 r/s
合并之后每秒读IO的次数w/s
合并之后每秒写IO的次数r/s + w/s = IOPS
- 在
rsec/s(rKB/s、rMB/s)和 wsec/s(wKB/s、wMB/s)
sec
是Sector(扇区)
,为512Byte
KB
和MB
是通过扇区的512Byte
进行的换算
avgrq-sz
- 一块磁盘可能存储数据的同时还存储日志,所以请求的IO大小是不一样的
- 该参数就是平均的请求数,注意,该值需要 * 512Byte 才是最终的结果,因为该值是以扇区为单位的
avgqu-sz
- 请求的IO队列的平均长度
(比较重要)
- HDD可能在4左右,SSD可以达到30左右
- 请求的IO队列的平均长度
await、r_await、w_await
- IO请求平均等待的时间,单位是ms
r_await
和w_await
分别对应读IO请求的等待
和写IO请求的等待
svctm
- 服务于IO请求的平均时间
- man文档中提示不要相信该值,以后会被移除
%util
- 磁盘是否空闲;不能简单的等同于IO的使用率;该值可以解释为磁盘是否繁忙
- 如果该值100% 不能简单的等同于磁盘的负载满了,达到了瓶颈
- 需要综合
avgqu-sz
、await
等其他指标进行综合判断磁盘是否达到瓶颈
三. MySQL的IO使用情况
1. iotop
1 | shell> iotop -u mysql # -u 表示监控哪个user的进程,所以前提是你的mysql服务是用mysql用户启动的 |
注意:
上述命令只能看到MySQL的线程ID(Thread ID)
2. performance_schema.threads
1 | mysql> use performance_schema; |
通过
threads表
中的信息,结合iotop -u mysql
的输出,就可以知道某个线程的io使用情况
MySQL 5.6 版本中没有
thread_os_id
这个列。
作业一:如何将iotop中的Thread ID和MySQL5.6中的threads表中的信息对应起来。
3. 存储结构对应关系
1 | +-------------+-------------+-------------+ |
SSD扇区的大小一般为4K或者8K。但是为了兼容HDD,SSD通过Flash Translation Layer (FTL)的方式转换成512B
4. O_DIRECT
fwrite / fsync
fwrite
是把数据写入文件系统层(Filesystem)(可能有cache),并不能保证写入Diskfsync
可以保证把数据写入到Disk(数据落盘)只通过
fwrite
写入数据特别快(因为有缓存),但随后调用fsync
就会很慢,这个速度取决于磁盘的IOPS
如果不手工执行fysnc
,当Filesystem的cache
小于10%
时,操作系统才会将数据刷入磁盘。所以可能存在数据丢失的风险,比如掉电
O_DIRECT
1
2
3
4
5
6
7
8
9+-------------------+ +-------------------+ +-------------------+
| | fwrite | | fsync | |
| Buffer Pool +---------------> Filesystem Cache +--------------> Disk |
| | | | | |
+--------+----------+ +-------------------+ +---------+---------+
| ^
| |
| innodb_flush_method = O_DIRECT |
+-----------------------------------------------------------------------+
> **`O_DIRECT`的设置参数是告诉系统`直接将数据写入磁盘`,跳过文件系统的缓存。等同于使用`裸设备`的效果**
四. sysbench
1. 安装
建议安装sysbenh-0.5
的版本1
2
3
4
5
6
7
8
9
10
11
12
13
14shell> https://github.com/akopytov/sysbench.git # 通过git clone得到源码
shell> cd sysbench
shell> ./autogen.sh
shell> ./configure --with-mysql-includes=/usr/local/mysql56/include/ --with-mysql-libs=/usr/local/mysql56/lib/ # 关联mysql的头文件和库
##
## 注意,如果我这里使用mysql5.7.9 的include和lib ,提示我 /usr/bin/ld: cannot find -lmysqlclient_r
##
shell> make -j 2 # -j 2 表示用几个cpu核心进行编译
shell> make install # 默认安装到 /usr/local/bin , 如果有自定义目录,configure增加参数 --prefix=自定义目录
shell> echo "export LD_LIBRARY_PATH=/usr/local/mysql56/lib/:$LD_LIBRARY_PATH" >> ~/.bashrc # 添加LD_LIBRARY_PATH
shell> source ~/.bashrc
shell> sysbench --version
sysbench 0.5
3. 测试
1 | # |
1 | # |
测试完成后执行
cleanup
如果是真实的测试max-time
设置成一周的时间run
期间可以使用iotop
或者iostat
进行观察