2 MySQL 基准测试

felix.shao2025-02-18

2 MySQL 基准测试

1 概述

 本章讨论 MySQL 和基于 MySQL 的应用的基准测试的重要性、策略和工具。最后特别讨论以下 sysbench,这是一款非常优秀的 MySQL 基准测试工具。

2 为什么需要基准测试

 基准测试可以完成以下工作,或者更多。

  • 验证基于系统的一些假设,确认这些假设是否符合实际情况。
  • 重现系统中的某些异常行为,以解决这些异常。
  • 测试系统当前的运行情况。了解当前系统的性能等。
  • 模拟比当前系统更高的负载,以找出系统随着压力增加而可能遇到的扩展性瓶颈。
  • 规划未来的业务增长。即测试后评估网络、硬件、以及其他相关的资源。
  • 测试应用适应可变环境的能力。例如,发现系统在随机的并发峰值的性能表现,或者是不同配置的服务器之间的性能表现。
  • 测试不同的硬件、软件和操作系统配置。
  • 证明新采购的设备是否配置正确。

3 基准测试的策略

 有两种主要的策略。

  1. 针对整个系统的整体测试。也称为集成式(full-stack)基准测试。
  2. 单独测试 MySQL。也称为单组件式(single-component)基准测试。

 两种策略测试关注的点是不一样的。

3.1 测试何种指标

 需要先明确测试的目标,测试目标决定了选择什么样的测试工具和技术,比如针对延迟(latency)和吞吐量(throughput)就需要采用不同的测试方法。
 测试主要考虑以下指标

  • 吞吐量。
  • 响应时间或者延迟。
  • 并发性。
  • 可拓展性。

3.2 基准测试方法

 一个好的基准测试需避免一些常见的错误。

  • 使用真实数据的子集而不是全集。如需要处理几百 GB 的数据,但测试数据只有 1 GB。
  • 使用错误的数据分布。
  • 使用不真实的分布参数。
  • 在多用户场景中,只做单用户的测试。
  • 在单服务器上测试分布式应用。
  • 与真实用户行为不匹配。
  • 反复执行同一个查询。
  • 没有检查错误。
  • 忽略了系统预热的过程。
  • 使用默认的服务器配置。
  • 测试时间太短。

 测试主要流程如下。

  1. 设计和规划基准测试。
  2. 基准测试应该运行多长时间。
  3. 获取系统性能和状态。需要记录的数据包括系统状态和性能指标,诸如 CPU 使用率、磁盘 I/O、网络流量统计、SHOW GLOBAL STATUS 计数器等,可以写脚本实现。
  4. 获得准确的测试结果。
  5. 运行基准测试并分析结果。最好是自动化测试。
  6. 将测试结果绘图展示。绘图能更加直观的观察到某些问题,典型的是周期性问题。可以使用 gnuplot 将文本第 5 步的文本数据绘制成图形。

 示例测试脚本 mysqltest.sh 如下,将 /root/benchmarks/running 目录删除后就可以停止循环任务了。

#!/bin/sh

INTERVAL=5
PREFIX=$INTERVAL-sec-status
RUNFIFE=/root/benchmarks/running
mysql -proot123456 -e 'SHOW GLOBAL VARIABLES' >> mysql-variables
while test -e $RUNFILE;do
  file=$(date +%F_%I)
  sleep=$(date + %s.%N | awk "{print $INTERVAL - (\$1 % $INTERVAL)}")
  sleep $sleep
  ts="$(date + "TS %s.%N %F %T")"
  loadavg="$(uptime)"
  echo "$ts $loadavg" >> $PREFIX-${file}-status
  mysql -proot123456 -e 'SHOW GLOBAL STATUS' >> $PREFIX-${file}-status &
  echo "$ts $loadavg" >> $PREFIX-${file}-innodbstatus
  mysql -proot123456 -e 'SHOW ENGINE INNODB STATUS\G' >> $PREFIX-${file}-innodbstatus & 
  echo "$ts $loadavg" >> $PREFIX-${file}-processlist
  mysql -proot123456 -e 'SHOW FULL PROCESSLIST\G' >> $PREFIX-${file}-processlist & 
  echo $ts
done
echo Exiting because $RUNFIFE does not exist.

 示例分析脚本为 analyze.sh。将上面生成的文件使用命令 ./analyze.sh 5-sec-status-2022-04-02 分析,这块目前分析失败了,猜是因为版本问题,后面回头再整下。

#!/bin/sh

awk '
  BEGIN {
	printf "#ts date time load QPS"
	fmt = " $.2f"
  }
  /^TS/ {
	ts      = substr($2, 1, index($2, ".") - 1);
	loaad   = NF - 2;
	diff    = ts - prev_ts;
	prev_ts = ts;
	printf "\n%s %s %s %s", ts, $3, $4, substr($load, 1, length($load)-1);
  }
  /Queries/ {
	printf fmt, ($2-Queries)/diff
	Queries=$2
  }
  ' "$@"

4 基准测试工具

 我们使用现有的工具可以解决大部分的问题。

4.1 集成式测试工具

 简单的列举如下。

  • ab。Apache HTTP 服务器基准测试工具。
  • http_load。和 ab 类似,但比 ab 更灵活。
  • JMeter。可以测试 Web 应用、FTP 服务器、JDBC 测试。

4.2 单组件式测试工具

 简单的列举如下。

  • mysqlslap。模拟服务器的负载,并输出计时信息。它包含在 MySQL 发行包中。支持自动生成查询 schema 的 SELECT 语句。
  • MySQL Benchmark Suitte (sql-bench)。基准测试套件。它是单线程的,主要用于测试服务器执行查询的速度。这个套件的主要好处是包含了大量预定义的测试,其最大的缺点主要有:它是单用户的,测试的数据集很少且用户无法使用指定的数据,并且同一个测试多次运行的结果可能会相差很大。
  • Super Smack。用于 MySQL 和 PostgreSQL 的基准测试工具,可以提供压力测试和负载生成,可以模拟多用户访问,可以加载测试数据到数据库,并支持使用随机数据填充测试表等。它是一个复杂而强大的工具。
  • Database Test Suite。
  • Percona's TPCC-MySQL Tool。
  • sysbench。它是一款多线程系统压测工具。它可以根据影响数据库服务器性能的各种因素来评估系统的性能。例如,可以用来测试文件 I/O、操作系统调度器、内存分配和传输速度、POSIX 线程,以及数据库服务器等。sysbench 支持 Lua 脚本语言,Lua 对于各种测试场景的设置可以非常灵活。sysbench 是我们非常喜欢的一种全能测试工具,支持 MySQL、操作系统和硬件的硬件测试。

:::  MySQL 提供了内置的 BENCHMARK() 函数,可以测试某些特定操作的执行速度。虽然用起来很方便,但不合适用来做真正的基准测试,因为很难理解真正要测试的是什么,而且测试的只是整个执行周期中的一部分环节。 :::

5 基准测试案例

 演示上面提到的基准测试工具进行测试的真实案例,来帮助我们入门。

5.1 http_load

 http_load 的安装如下。

$ wget http://www.acme.com/software/http_load/http_load-09Mar2016.tar.gz
$ tar zxvf http_load-09Mar2016.tar.gz
$ cd http_load-09Mar2016
# make install 时若出现 /usr/local/man/man1 目录不存在,则使用 mkdir -p /usr/local/man/man1 创建即可
$ make && make install

 下面是简单的使用 http_load。
 首先创建 urls.txt 文件,输入如下的 URL。

http://www.mysqlperformanceblog.com/
http://www.mysqlperformanceblog.com/page/2/
http://www.mysqlperformanceblog.com/mysql-patches/
http://www.mysqlperformanceblog.com/mysql-performance-presentations/
http://www.mysqlperformanceblog.com/2006/09/06/slow-query-log-analyzes-tools/

 循环请求给定的 URL 列表。测试命令如下。

# 简单地输出统计信息
$ http_load -parallel 1 -seconds 10 urls.txt
22 fetches, 1 max parallel, 0 bytes, in 10.0008 seconds
0 mean bytes/connection
2.19983 fetches/sec, 0 bytes/sec
msecs/connect: 219.921 mean, 231.738 max, 212.422 min
msecs/first-response: 220.171 mean, 232.014 max, 212.775 min
HTTP response codes:
  code 302 -- 22

# 尽可能快地循环请求给定的 URL 列表
$ http_load -parallel 5 -seconds 10 urls.txt
110 fetches, 5 max parallel, 0 bytes, in 10.0009 seconds
0 mean bytes/connection
10.999 fetches/sec, 0 bytes/sec
msecs/connect: 219.397 mean, 236.409 max, 209.913 min
msecs/first-response: 220.06 mean, 236.472 max, 211.1 min
HTTP response codes:
  code 302 -- 110

# 根据预估的访问请求率(比如每秒 5 次)来做压力模拟测试
$ http_load -rate 5 -seconds 10 urls.txt
45 fetches, 5 max parallel, 0 bytes, in 10.0129 seconds
0 mean bytes/connection
4.49421 fetches/sec, 0 bytes/sec
msecs/connect: 262.107 mean, 527.036 max, 225.991 min
msecs/first-response: 252.711 mean, 529.103 max, 210.778 min
HTTP response codes:
  code 302 -- 45

# 模拟更大的负载,可以将访问请求率提高到每秒 20 次请求。这样,连接和请求响应时间都会随着负载的提高而增加。
$ http_load -rate 20 -seconds 10 urls.txt
190 fetches, 11 max parallel, 0 bytes, in 10.0187 seconds
0 mean bytes/connection
18.9645 fetches/sec, 0 bytes/sec
msecs/connect: 246.765 mean, 273.503 max, 226.815 min
msecs/first-response: 231.528 mean, 257.34 max, 212.344 min
HTTP response codes:
  code 302 -- 190

5.2 MySQL 基准测试套件

 略。

5.3 sysbench

 推荐。安装 yum install sysbench -y

  1. sysbench 的 CPU 基准测试。
# 查看 CPU 配置
$ cat /proc/cpuinfo 

# 测试 CPU,通过时间可以对比 CPU 性能结果
$ sysbench --test=cpu --cpu-max-prime=20000 run
...
sysbench 1.0.17 (using system LuaJIT 2.0.4)
...
General statistics:
    total time:                          10.0005s
    total number of events:              3980
...
  1. sysbench 的文件 I/O 基准测试。
# 创建一个数据集
$ sysbench fileio --file-total-size=1G prepare

# 运行,针对不同的 I/O 类型有不同的测试选项。seqwr:顺序写入;seqrewr:顺序重写;seqrd:顺序读取;rndrd:随机读取;rndwr:随机写入;rndrw:混合随机读/写。
$ sysbench fileio --file-total-size=1G --file-test-mode=rndrw  --time=300 --max-requests=0 run
sysbench 1.0.17 (using system LuaJIT 2.0.4)
...
Threads started!

File operations:
    reads/s:                      994.61
    writes/s:                     663.07
    fsyncs/s:                     2121.94
...
General statistics:
    total time:                          300.0569s
    total number of events:              1133978
...
Threads fairness:
    events (avg/stddev):           1133978.0000/0.00
    execution time (avg/stddev):   299.0384/0.00

# 清除生成的测试文件
$ sysbench fileio --file-total-size=1G cleanup
  1. sysbench 的 OLTP 基准测试。  略。测试事务的。

  2. sysbench 的其他特性。  和数据库没有关系的性能。

  • 内存。测试内存的连续读写性能。
  • 线程。测试线程调度器的性能。
  • 互斥锁。测试互斥锁的性能。
  • 顺序写。测试顺序写的性能。

 完整的 sysbench 需查阅相关文档。

5.4 数据库测试套件中的 db2 TPC-C 测试

 略。

5.5 Percona 的 TPCC-MySQL 测试工具

 略,MySQL 性能测试推荐。

参考文献

  • [高性能 MySQL]
Last Updated 2/18/2025, 5:05:12 PM