news 2026/10/30 2:38:05

附-01 · MySQL 压测与容量规划 —— sysbench 基准测试、容量评估与参数基线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
附-01 · MySQL 压测与容量规划 —— sysbench 基准测试、容量评估与参数基线

附-01 · MySQL 压测与容量规划 —— sysbench 基准测试、容量评估与参数基线

系列定位:《MySQL 数据库全栈运维实战系列》第 附-01 篇(番外),与《Oracle 数据库全栈运维实战系列(VMware 版)》同构对标。适用版本:MySQL 8.0(5.7 差异随文标注)。官方文档:MySQL 8.0 Reference Manual、sysbench 官方文档(github.com/akopytov/sysbench)。


一、为什么压测先行

很多团队上线前不压测,上线后才发现"这台 32G 虚机撑不住 5000 TPS"。容量规划的核心逻辑是:先用 sysbench 在与生产同规格的虚机上跑出这台机器的 TPS 上限,再按业务峰值 × 安全系数(2~3 倍)倒推需要多少台、多大内存、什么磁盘。没有压测数据的容量规划就是拍脑袋。

图 1

概念说明类比 Oracle
sysbenchMySQL 官方生态最常用的 OLTP 压测工具Oracle Swingbench / ORION
TPS每秒事务数transactions per second
QPS每秒查询数?
P99 延迟99 分位响应时间response time percentile
安全系数峰值 × 2~3 倍留余量capacity headroom

VMware 虚机环境注意事项:压测结果只在"与生产同规格、同置盘方式、同资源预留"的虚机上才有意义。压测前务必:① 固定 vCPU 数与内存(不要开热添加);② 磁盘确认 thick eager zeroed 或 SSD 直通(thin 盘在首次写入时会做 zeroing,污染结果);③ 关闭宿主机上其他大负载 VM;④ 压测分冷启动(重启 MySQL 后跑)和热数据(预热 Buffer Pool 后跑)两轮,分别记录。


二、sysbench 安装与三个阶段

图 2

# CentOS 7 / Rocky Linux 安装(解释:官方 yum 源或直接下二进制) curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash sudo yum -y install sysbench # 验证版本(解释:8.0 配套建议 sysbench 1.0.20+) sysbench --version # sysbench 1.0.20

sysbench 压测分三段:prepare(造数据)→run(压测)→cleanup(清数据)。

# 通用连接参数(解释:抽到变量里,三段复用) SB_HOST=127.0.0.1 SB_PORT=3306 SB_USER=sbtest SB_PWD='sbtest_pwd' SB_DB=sbtest # 先建库和账号(解释:sysbench 不会自动建) mysql -uroot -p -e "CREATE DATABASE sbtest; CREATE USER 'sbtest'@'%' IDENTIFIED BY 'sbtest_pwd'; GRANT ALL PRIVILEGES ON sbtest.* TO 'sbtest'@'%'; FLUSH PRIVILEGES;"

2.1 prepare:造数据

# 造 10 张表,每张 100 万行(解释:oltp_read_write 是经典 OLTP 模型) sysbench --mysql-host=$SB_HOST --mysql-port=$SB_PORT \ --mysql-user=$SB_USER --mysql-password=$SB_PWD \ --mysql-db=$SB_DB \ oltp_read_write \ --tables=10 --table-size=1000000 \ prepare

2.2 run:压测

# 20 并发线程,跑 60 秒(解释:先短后长,60s 看趋势,再跑 300s 拿稳定值) sysbench --mysql-host=$SB_HOST --mysql-port=$SB_PORT \ --mysql-user=$SB_USER --mysql-password=$SB_PWD \ --mysql-db=$SB_DB \ oltp_read_write \ --tables=10 --table-size=1000000 \ --threads=20 --time=60 --report-interval=10 \ run

典型输出(解释:重点看这几个数):

SQL statistics: queries performed: read: 456000 write: 128000 other: 64000 total: 648000 transactions: 32400 (540.0 per sec.) queries: 648000 (10800.0 per sec.) ignored errors: 0 (0.0 per sec.) reconnects: 0 (0.0 per sec.) Throughput: events/s (eps): 540.00 latency (ms): min: 2.1 avg: 37.0 max: 480.5 99th percentile: 85.2 threads fairness: 0.99

2.3 cleanup:清数据

sysbench --mysql-host=$SB_HOST --mysql-port=$SB_PORT \ --mysql-user=$SB_USER --mysql-password=$SB_PWD \ --mysql-db=$SB_DB \ oltp_read_write --tables=10 \ cleanup

三、常用压测模型与场景选择

测试脚本场景适用业务
oltp_read_write混合读写(默认 14 SELECT + 4 UPDATE + 2 INSERT + 2 DELETE)通用 OLTP,最常用
oltp_read_only只读报表/读库
oltp_write_only只写写入密集型
oltp_point_select单点主键查询主键 KV 查询
oltp_update_index/non_index索引列/非索引列更新写放大评估
select_random_ranges范围扫描报表扫描
# 压测读库(解释:从库/只读节点用 read_only 模型) sysbench ... oltp_read_only --threads=50 --time=300 run # 压测写能力(解释:主库写上限) sysbench ... oltp_write_only --threads=32 --time=300 run

四、并发梯度:找到拐点

图 3

图 4

# 梯度压测(解释:依次跑 10/20/50/100/200 并发,记录 TPS 与 P99) for t in 10 20 50 100 200; do echo "=== threads=$t ===" sysbench ... oltp_read_write --threads=$t --time=60 run 2>&1 | grep -E "transactions:|99th" done

典型拐点曲线:

并发线程TPSP99 延迟结论
1038025ms未饱和
2054037ms接近最优
5062095ms到顶
100580220ms开始下降(CPU/IO 饱和)
200420680ms过饱和

结论:这台虚机在 50 并发附近 TPS 见顶(约 620),P99 < 100ms。业务峰值按 200 TPS 算,单机够;按 1000 TPS 算,要 2 主从读写分离。


五、容量评估方法论

图 5

图 6

5.1 内存怎么算

项经验值
innodb_buffer_pool_size物理内存 60~70%( dedicated DB 虚机)
每个连接线程内存sort_buffer + join_buffer + read_buffer ≈ 4~8MB/连接
其他(OS、连接、tmp table)留 2~4G

32G 虚机:BP=20G,max_connections=500,预留 OS+连接约 8G,刚好。

5.2 磁盘怎么算

总磁盘 = 数据 + 索引 + redo + binlog(7天) + 备份空间 + 30% 余量
  • 数据:sysbench 跑出单行大小 × 预估行数。
  • binlog:按峰值 TPS × 平均 row 大小 × 86400 × 7 天估。
  • 备份:至少保留 2 份全备 + 当天增量,建议数据盘的 1.5 倍。

5.3 IOPS 怎么算

# 压测时同时盯主机 IO(解释:iostat 看 %util 和 await) iostat -xz 2 5 # 如果 await > 20ms 且 %util 接近 100%,说明磁盘是瓶颈,要换 SSD/加盘

六、参数基线(8.0 生产推荐 my.cnf)

[mysqld] # ===== 基础 ===== user = mysql port = 3306 datadir = /data/mysql socket = /data/mysql/mysql.sock character-set-server = utf8mb4 collation-server = utf8mb4_0900_ai_ci # ===== 内存(按物理内存 60~70%)===== innodb_buffer_pool_size = 20G # 32G 虚机示例 innodb_buffer_pool_instances = 8 innodb_log_buffer_size = 64M # ===== redo(8.0.30+ 统一参数)===== innodb_redo_log_capacity = 2G innodb_flush_log_at_trx_commit = 1 # 双 1,不动 innodb_flush_method = O_DIRECT # ===== binlog ===== log_bin = /data/mysql-bin/mysql-bin binlog_format = ROW binlog_expire_logs_seconds = 604800 # 7 天 sync_binlog = 1 # 双 1,不动 # ===== 连接 ===== max_connections = 500 wait_timeout = 60 interactive_timeout = 300 # ===== 临时表/排序 ===== tmp_table_size = 128M max_heap_table_size = 128M sort_buffer_size = 2M join_buffer_size = 2M # ===== IO(SSD 直通盘)===== innodb_io_capacity = 2000 innodb_io_capacity_max = 4000 # ===== 慢日志 ===== slow_query_log = 1 long_query_time = 1 slow_query_log_file = /data/mysql-slow/slow.log

类比 Oracle:Oracle 容量规划用 ORION 压磁盘 IO、Swingbench 压业务负载;MySQL 生态对应就是 sysbench(业务负载)+ fio(裸盘 IO)。Oracle 有 Automatic Memory Management,MySQL 内存参数要自己按上面公式算,没有自动 SGA 调优。


七、上线后基线对比

压测不是一次性动作。上线后每周把生产监控曲线和压测基线对比:

指标压测基线生产实测偏差
50 并发 TPS620580-6%(正常抖动)
Buffer Pool 命中率99.9%99.2%略低,关注
P99 延迟85ms120ms偏高,查慢 SQL
磁盘 await5ms18msIO 紧张,考虑 SSD

八、踩坑记录(实测汇总)

#坑现象解决
1在 thin 盘上压测首次写入 zeroing,TPS 忽高忽低thick eager zeroed 或 SSD
2压测没预热第一轮冷数据全落盘,TPS 极低先跑一轮 prepare 后预热再正式压
3压测机和 MySQL 同机CPU/IO 互相干扰压测客户端单独一台虚机
4并发一路加到 1000过饱和后 TPS 反而掉找拐点,别盲目加并发
5拿默认参数压测Buffer Pool 才 128M,结果不可信先按基线 my.cnf 调优再压
6只看 avg 延迟avg 37ms 但 P99 480ms必看 99th percentile
7业务量拍脑袋上线 3 个月磁盘满按数据增长模型提前 6 个月扩
8备份空间不算进总盘全备没地方放总盘预留备份 1.5 倍数据量
9VMware 没关其他 VMnoisy neighbor 污染数据压测窗口独占宿主机
10压测脚本用 oltp_read_only 测写库结果完全失真按业务类型选脚本

九、本文要点速记

  1. 压测先行:同规格虚机上跑 sysbench,拿到单机 TPS 上限再做容量规划。
  2. 三段式:prepare → run → cleanup,别忘 cleanup。
  3. 找拐点:梯度加并发,TPS 见顶 + P99 飙升处就是最优并发。
  4. 内存公式:Buffer Pool 60~70% 物理内存,连接内存按 max_connections×per-thread 算。
  5. 双 1 不动:压测时别为了好看把 flush_log/sync_binlog 关了,那不是生产配置。
  6. 上线后对比基线:每周看生产指标 vs 压测基线,偏差超过 20% 要查原因。

十、参考资料(官方正式文档)

主题官方链接
MySQL 8.0 Reference Manual(InnoDB 配置)https://dev.mysql.com/doc/refman/8.0/en/innodb-configuration.html
sysbench(GitHub 官方仓库)https://github.com/akopytov/sysbench
sysbench OLTP 脚本说明https://github.com/akopytov/sysbench/tree/master/sysbench/tests/include/oltp_legacy
fio(裸盘 IO 压测)https://github.com/axboe/fio
InnoDB Buffer Pool 配置https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-pool-configuring.html
Binary Log 配置https://dev.mysql.com/doc/refman/8.0/en/binary-log-config.html

本文章属于《MySQL 数据库全栈运维实战系列》番外篇。欢迎收藏、交流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/30 2:34:34

鸿蒙多窗适配:不要把窗口宽度当成内容区宽度【鸿蒙心迹】

TL;DR:多窗与分栏下应以实际内容区而非窗口总宽度驱动断点。本文用 ContainerReader 拆解测量对象、布局决策与回归检查;示例仅作接口说明,尚未完成本机 SDK 或真机编译运行。 多窗把页面挤坏了:不要把窗口宽度当成内容区宽度【鸿蒙心迹】 > 适用场景:同一页面会出现在…

作者头像 李华
网站建设 2026/10/30 2:34:34

AI配音如何制作多角色对话?旁白、人物台词与音色搭配指南

讲解视频、故事短片、情景剧和知识类内容&#xff0c;有时不只有一个说话人&#xff0c;还需要旁白、人物台词甚至多人之间的对话。如果每个角色都由真人录制&#xff0c;不仅需要协调录音&#xff0c;还要反复调整语速和音量。AI配音可以降低这类内容的制作门槛&#xff0c;但…

作者头像 李华
网站建设 2026/10/30 2:31:47

微信小程序:变脸游戏

&#x1f3af;实现功能点击脸谱图片&#xff0c;随机切换脸谱&#xff1b;摇晃手机&#xff0c;触发摇一摇变脸&#xff0c;弹出成功提示&#xff1b;✨作业扩展&#xff1a;点击、摇晃两种变脸方式都统计次数&#xff0c;页面实时展示累计变脸总次数&#xff1b;传感器防抖处理…

作者头像 李华
网站建设 2026/10/30 2:30:54

TF-IDF 基线——用词频与逆文档频率跑通第一条提取链路

目标&#xff1a;理解“一个词在本文档中重要&#xff0c;但在整个语料库中不常见&#xff0c;才可能是主题词”&#xff0c;并用 jieba 或 sklearn 写出可运行的关键词提取代码。 TF-IDF 的核心思想是&#xff1a;词频&#xff08;TF&#xff09;越高、逆文档频率&#xff08…

作者头像 李华
网站建设 2026/10/30 2:29:42

01-原理篇-读懂无线信号-空口指标体系完全指南

01-原理篇-读懂无线信号&#xff1a;空口指标体系完全指南 无线问题排查的第一步&#xff0c;不是敲命令&#xff0c;而是读懂这些指标。 本文指标基于企业级 Wi-Fi 5&#xff08;802.11ac&#xff09;和 Wi-Fi 6&#xff08;802.11ax&#xff09;设备&#xff0c;适用于 Cisco…

作者头像 李华
网站建设 2026/10/30 2:29:16

Linux FFmpeg深度解析之avformat_seek_file调用流程与实战(九)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》作者 博主新书推荐&#xff1a;《Android系统多媒体进阶实战》&#x1f680; Android Audio工程师专栏地址&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; Android多媒体专栏地址&a…

作者头像 李华