今天给大家分享一篇在测试环境或者是自己想检验自己MySQL性能的文章
实验环境:
Rocky Linux 8
镜像:Rocky-8.6-x86_64-dvd.iso
1. 创建一个大文件作为虚拟磁盘
[root@localhost ~] dd if=/dev/zero of=/tmp/slowdisk.img bs=1M count=100
记录了100+0 的读入
记录了100+0 的写出
104857600 bytes (105 MB, 100 MiB) copied, 0.334391 s, 314 MB/s
这将创建一个100MB的文件/tmp/slowdisk.img。
2. 使用losetup将文件虚拟成块设备
[root@localhost ~] losetup -f --show /tmp/slowdisk.img
/dev/loop0
这会输出一个类似于/dev/loopX(X是数字)的设备名,表示你的虚拟磁盘。
注意:确保/var/lib/mysql/目录有足够的空间,或者选择一个其他有足够空间的目录。
3. 创建文件系统并挂载
由于只是模拟,通常不会真正在这个设备上创建文件系统(因为后续我们要用特定的方式来模拟延迟,而不是真正的文件系统延迟)。但如果你真的想这么做,可以使用如下命令(以ext4为例):
[root@localhost ~] mkfs.ext4 /dev/loop0
mke2fs 1.45.6 (20-Mar-2020)
丢弃设备块: 完成
创建含有 102400 个块(每块 1k)和 25688 个inode的文件系统
文件系统UUID:7ea37143-3461-45a1-bbce-1b3008535be1
超级块的备份存储于下列块:
8193, 24577, 40961, 57345, 73729
正在分配组表: 完成
正在写入inode表: 完成
创建日志(4096 个块)完成
写入超级块和文件系统账户统计信息: 已完成
[root@localhost ~] mkdir -p /tmp/slowdisk && mount /dev/loop0 /tmp/slowdisk
4. 配置MySQL
将 binlog 的位置设置到 /tmp/slow,开启双 1 刷盘参数
vim /etc/my.cnf
log-bin=/tmp/slowdisk/binlog
innodb_flush log_at_trx_commit=1
5. 用 mysqlslap 进行压力测试
mysqlslap 使用方法介绍
通过mysqlslap –help可以获得可用的选项,这里列一些主要的参数,更详细的说明参考官方手册。
1) concurrency代表并发数量,多个可以用逗号隔开,例如:concurrency=10,50,100, 并发连接线程数分别是10、50、100个并发。
2) --engines代表要测试的引擎,可以有多个,用分隔符隔开。
3) --iterations代表要运行这些测试多少次。
4) --auto-generate-sql 代表用系统自己生成的SQL脚本来测试。
5)--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
6) --number-of-queries 代表总共要运行多少次查询。每个客户端运行的查询数量可以用查询总数/并发数来计算。
7) --debug-info 代表要额外输出CPU以及内存的相关信息。
8) --number-int-cols :创建测试表的 int 型字段数量
9) --auto-generate-sql-add-autoincrement : 代表对生成的表自动添加auto_increment列,从5.1.18版本开始
10) --number-char-cols 创建测试表的 char 型字段数量。
11) --create-schema 测试的schema,MySQL中schema也就是database。
12) --query 使用自定义脚本执行测试,例如可以调用自定义的一个存储过程或者sql语句来执行测试。
13) --only-print 如果只想打印看看SQL语句是什么,可以用这个选项。
开始测试
[root@localhost ~] mysqlslap --user=root --password=lmx --host=127.0.0.1
--concurrency=50 --iterations=200
--query="insert into a1 values()" --create="create table a1(b int primary key AUTO_INCREMENT)"
mysqlslap: [Warning] Using a password on the command line interface can be insecure.
Benchmark
Average number of seconds to run all queries: 0.116 seconds #运行所有语句的平均秒数
Minimum number of seconds to run all queries: 0.105 seconds #运行所有语句的最小秒数
Maximum number of seconds to run all queries: 0.144 seconds #运行所有语句的最大秒数
Number of clients running queries: 50 #客户端数量
Average number of queries per client: 1 #每个客户端运行查询的平均数
通过 iostat 可以观察到 binlog 所在的块设备 IO 发生饱和:
- dm-0 (/dev/mapper/dm-slow) 设备的 IO 出现了排队(aqu-sz),使用率饱和。
- loop3 是 dm-0 背后的块设备,其 IO 还有充足的能力,可证明 dm-0 带有 IO 延迟。
[root@localhost ~] yum -y install sysstat
[root@localhost ~]iostat -x 1 -p dm-0 -p loop3
通过 pt-ioprofile 观察 MySQL 的 IO 消耗时间
#时区和时间一定要对
[root@localhost ~] tar -zxvf percona-toolkit-3.7.0_x86_64.tar.gz
[root@localhost ~] yum -y install perl strace
[root@localhost ~] cd percona-toolkit-3.7.0/bin/
[root@localhost bin]./pt-ioprofile
- read:从文件中读出数据。要读取的文件用文件描述符标识,数据读入一个事先定义好的缓冲区。
- write:把缓冲区的数据写入文件中。
- pread:由于lseek和read调用之间,内核可能会临时挂起进程,所以对同步问题造成了问题,
调用pread相当于顺序调用了lseek和read,这两个操作相当于一个捆绑的原子操作。 - pwrite:由于lseek和write调用之间,内核可能会临时挂起进程,所以对同步问题造成了问题,
调用pwrite相当于顺序调用了lseek 和write,这两个操作相当于一个捆绑的原子操作。 - fsync:确保文件所有已修改的内容已经正确同步到硬盘上,该调用会阻塞等待直到设备报告IO完成。
- filename:与磁盘交互的文件名称
结果:
我们制造了一个慢 IO 的设备,将 MySQL binlog 放在其中,制造了 binlog IO 慢的场景。有了这个手段,之后我们可以分析 MySQL 在局部文件 IO 慢时,哪些状态量会发生变化,以及 MySQL 会发生什么行为。
下篇给大家详细的讲解 DBA如何使用pt-ioprofile