sysbench/TPC-C/自定义脚本:数据库压测工具对比与实战流程

十五年数据库相关经验,做过 DBA、架构师、技术顾问。不求"颠覆",只求"靠谱"。


功能测试通过了,不代表数据库能上线。

我见过太多项目:开发环境跑得好好的,测试环境验证也没问题,一上生产------高峰期 TPS 掉到平时的十分之一,响应时间从几十毫秒飙到几秒,连接数直接打满。

原因很简单:功能测试验证的是"能不能跑",压测验证的是"能不能扛"。这两个问题完全不同。一个系统的功能可以在低并发、小数据量下验证,但性能必须在接近生产的压力条件下才能暴露真实水平。

今天把数据库压测的完整流程讲清楚------场景设计、工具选型、指标监控、瓶颈定位。跟着这个流程走一遍,上线之前心里有数。


01 压测场景设计:测什么,怎么测

压测不是"跑个工具、看个 TPS"就完事了。场景设计不对,测出来的数据没有参考价值。

数据库压测通常要覆盖三类场景:

峰值模拟

模拟业务高峰期的并发压力。比如电商大促、财务月结、月初报表生成------这些时段的并发量是平时的数倍甚至十几倍。

怎么设计:先采集生产环境的并发基线数据(平时 QPS 多少、峰值 QPS 多少、高峰期持续时间),然后按峰值的 1.2-1.5 倍设置压测并发量。留 20-50% 的余量,是因为上线后业务可能继续增长。

混合负载

真实业务不是单一类型的 SQL 在跑。读写混合、OLTP + OLAP 混合、长事务 + 短事务混合------不同类型的 SQL 竞争同一套资源,压力模型和单一负载完全不同。

怎么设计:按生产环境的 SQL 类型分布比例配置压测脚本。比如 70% 读 + 25% 写 + 5% 复杂查询。只测纯读写或者只测简单查询,测出来的 TPS 再高也没有参考价值。

长稳测试

压测跑 5 分钟没问题,不代表跑 24 小时没问题。内存泄漏、连接泄漏、统计信息过时、WAL 积压------这些问题在短时间压测里不会出现,长时间运行才会暴露。

怎么设计:以峰值 80% 的并发量持续跑 12-24 小时,监控 TPS、延迟、资源利用率是否有漂移。如果 TPS 逐步下降或延迟逐步上升,说明系统有隐性瓶颈。

踩坑提醒:不要只跑峰值。峰值压测验证的是"能不能扛住最高压力",长稳测试验证的是"能不能持续稳定运行"。两者缺一不可。


02 压测工具选型:用什么测

数据库压测工具不少,选哪个取决于你要测什么。

sysbench

最通用的数据库压测工具,支持 MySQL、PostgreSQL 等。

测什么:OLTP 基准性能------读写混合场景下的 TPS/QPS、延迟分布。

怎么用

bash 复制代码
# 准备数据(100万条记录)
sysbench oltp_common --mysql-host=127.0.0.1 --mysql-db=testdb \
  --table-size=1000000 --tables=10 prepare

# 压测(128并发,跑300秒)
sysbench oltp_read_write --mysql-host=127.0.0.1 --mysql-db=testdb \
  --threads=128 --time=300 --report-interval=10 run

优点 :简单易用、开箱即用、结果直观。 缺点:模型固定,只能测标准的 OLTP 场景,不能模拟自定义业务 SQL。

TPC-C

标准的联机事务处理基准测试,更贴近真实的交易场景。

测什么:订单处理类业务(新建订单、支付、发货、库存查询的混合负载)。

优点 :场景贴近真实业务、有标准化的评估指标(tpmC)。 缺点:部署复杂、配置繁琐、需要专门的测试工具(BenchmarkSQL 等)。

自定义脚本

用自己的业务 SQL 写压测脚本。

测什么:你的真实业务场景,而不是通用模型。

怎么做:把生产环境采集到的 Top SQL 提取出来,用 Python/JMeter 写成并发脚本,按实际比例混合执行。

优点 :最贴近真实业务,测出来的数据直接反映生产表现。 缺点:需要花时间准备脚本,不是开箱即用。

对比总结

工具 适用场景 部署难度 贴近真实业务 推荐度
sysbench OLTP 基准性能 低(通用模型) 快速验证推荐
TPC-C 交易类业务基准 中(标准交易模型) 标准化评估推荐
自定义脚本 真实业务场景 上线前必做

建议:先用 sysbench 做快速基准测试(半天搞定),再用自定义脚本做业务场景压测(需要 1-2 天准备)。两步都做,结果才有参考价值。


03 关键指标监控:看什么

压测过程中,不能只看 TPS。TPS 是一个汇总指标,它高不代表一切都好。

需要同时监控的核心指标:

TPS/QPS:每秒事务数/查询数。反映整体吞吐能力。但要看稳定值,不要看峰值------峰值可能只维持了几秒就掉下来了。

延迟分布:不能只看平均延迟,要看 P50、P95、P99。平均延迟 50ms,但 P99 是 5 秒------意味着 1% 的请求要等 5 秒,这些用户会感知到"系统卡了"。

资源利用率

  • CPU:如果 CPU 持续 90%+,说明计算能力是瓶颈
  • 内存:如果 swap 开始使用,说明内存不够了
  • 磁盘 I/O:如果 iowait 持续偏高,说明磁盘 I/O 是瓶颈
  • 网络:如果网络带宽打满,说明网络是瓶颈

连接数:活跃连接数 vs 最大连接数。如果活跃连接数持续接近最大连接数,说明连接数不够了,新的请求会排队等待。

锁等待:并发场景下的锁等待次数和等待时间。如果锁等待持续增长,说明并发控制是瓶颈。

踩坑提醒:压测报告不能只写"TPS 达到多少"。完整的压测报告应该包含:TPS 趋势图、延迟分布(P50/P95/P99)、资源利用率曲线、瓶颈分析。少任何一个维度,报告都是不完整的。


04 瓶颈定位与调优:从指标异常到根因

压测发现了瓶颈,下一步是找到根因。

场景一:TPS 上不去,CPU 也不高

现象:并发量增加了,但 TPS 没有同步增长,CPU 利用率只有 30-40%。

可能原因

  • I/O 瓶颈 :磁盘读写速度跟不上,数据库在等 I/O。查 iostat%utilawait
  • 锁竞争:多个事务竞争同一把锁,大量时间在等待。查锁等待信息。
  • 连接数不够:最大连接数设小了,新请求在排队。查活跃连接数。

排查步骤

  1. 先看资源利用率(CPU、内存、I/O),排除资源瓶颈
  2. 再看锁等待,排除并发竞争
  3. 最后看连接数和配置参数

场景二:TPS 先高后低

现象:压测开始时 TPS 很高,跑了十几分钟后逐步下降。

可能原因

  • Buffer Pool 热数据未预热:刚开始读的数据不在缓存里,要磁盘 I/O。跑了十几分钟后热数据加载完了,但新的冷数据开始进来,缓存命中率波动。
  • 统计信息过时:数据量增长导致执行计划漂移,优化器选了更差的路径。
  • WAL/日志积压:写入量大,日志刷盘速度跟不上,阻塞写入。

排查步骤

  1. 看缓存命中率趋势(是否逐步下降)
  2. 看执行计划变化(是否有 SQL 的计划变了)
  3. 看 WAL/日志文件大小和刷盘延迟

场景三:延迟飙升

现象:TPS 没怎么变,但平均延迟从 50ms 飙升到 5 秒。

可能原因

  • 大事务阻塞:一个批量更新的大事务在跑,锁住了大量数据,其他事务排队等待。
  • 临时表爆满:复杂查询产生的临时表占满了磁盘空间或内存。
  • 排序/聚合溢出到磁盘work_mem 不够,排序操作从内存溢出到磁盘,速度骤降。

排查步骤

  1. 查当前正在执行的 SQL(有没有大事务)
  2. 查锁等待信息(有没有阻塞链)
  3. 查临时文件和排序溢出(PostgreSQL 查 pg_stat_databasetemp_files

对比:压测环境 vs 生产环境的差异

维度 压测环境 生产环境 差异影响
数据量 通常是生产的 1/10 或更少 全量数据 数据量小导致索引选择率不同,执行计划可能偏差
负载模式 模拟的固定并发 真实的波动并发 固定并发测不出突发流量的影响
硬件配置 可能低于生产 实际配置 配置低导致压测结果偏保守
后台任务 通常没有 备份、归档、统计信息更新 后台任务会占用资源,影响性能
网络延迟 通常在本机或同机房 可能跨机房、跨地域 网络延迟影响响应时间

踩坑提醒:压测结果一定要打折扣。如果压测环境的数据量是生产的 1/10,测出来的 TPS 在生产环境下可能只有 50-70%。预留足够的性能余量是 DBA 的基本素养。


决策框架:压测结果怎么判定

压测跑完了,结果怎么判定?分四档:

通过:TPS 达到目标值,P99 延迟在可接受范围内,资源利用率有 30%+ 余量,长稳测试 24 小时无漂移。→ 直接上线。

优化后通过:TPS 接近目标值(差 10-20%),瓶颈明确且可调(参数调整、索引优化)。→ 调优后复测,复测通过再上线。

需架构调整:TPS 远低于目标值(差 50%+),单机性能到达上限。→ 需要考虑读写分离、分库分表、缓存层等架构调整。

不可行:压测过程中出现数据不一致、崩溃、严重性能退化且无法定位根因。→ 不能上线,需要重新评估方案。


态度转变:我以前也不做压测

干 DBA 前三年,我上线系统也不做压测。

原因很简单:觉得麻烦。功能测试跑通了,SQL 也能执行,为什么还要专门搭压测环境、写脚本、跑半天?上线之后有问题再调呗。

直到有一次上线一个报表系统。功能测试通过,上线当天正好赶上月初出报表。几百个并发用户同时跑复杂查询------数据库直接卡死,CPU 100%,连接数打满,所有业务都受影响。回退。第二次上线前做了压测,发现是几个核心查询缺了复合索引,加上之后重新压测,TPS 提升了 8 倍。上线后稳如泰山。

那次之后,我做任何上线,压测是必选项。不是因为"流程要求",是因为"吃过亏"。


深度分析:为什么"跑通"和"扛住"差这么远

很多人以为"SQL 能执行 = 性能没问题"。

事实上,一条 SQL 在低并发下跑 100ms,在高并发下可能跑 10 秒。不是因为 SQL 变了,是因为资源竞争变了。

低并发时,磁盘 I/O 够用、缓存命中率高、没有锁竞争。高并发时,磁盘 I/O 被多个查询分摊、缓存命中率下降、锁竞争加剧------同一条 SQL 的执行环境完全不同。

压测的价值就在于:在可控的条件下,模拟出生产环境的资源竞争状态,提前暴露问题。等上线之后在生产环境里暴露问题,代价就大了。


上线前压测验收检查清单

场景覆盖

  • 峰值模拟压测通过(1.2-1.5 倍峰值并发)
  • 混合负载压测通过(读写比例与实际一致)
  • 长稳测试通过(12-24 小时无 TPS/延迟漂移)

指标达标

  • TPS/QPS 达到目标值
  • P99 延迟在可接受范围内
  • CPU 利用率 < 80%
  • 内存无 swap
  • 磁盘 I/O 无瓶颈(%util < 80%)
  • 连接数余量 > 30%

瓶颈排查

  • 无持续性锁等待
  • 无大事务阻塞
  • 无执行计划漂移
  • 无缓存命中率骤降

文档输出

  • 压测报告完整(TPS 趋势、延迟分布、资源利用率、瓶颈分析)
  • 压测环境与生产环境的差异说明及折扣系数
  • 上线后性能监控基线已建立
  • 回退方案已准备

总结

数据库上线,功能跑通只是第一步,性能扛住才是真过关。

压测不是"跑个工具看个 TPS",是场景设计(峰值 + 混合 + 长稳)、工具选型(sysbench + 自定义脚本)、指标监控(TPS + 延迟分布 + 资源利用率)、瓶颈定位的完整流程。少任何一个环节,压测结果都没有参考价值。

功能测试通过不代表能上线,压测没过都是白搭。压测这件事,越早做越好------别等上线那天在 production 里做压测。

后续我会继续分享数据库容量规划、安全审计这些话题,跟着我一篇篇学,数据库这块就没问题了。

有问题评论区见。


十五年数据库领域老炮。关注我,一起把数据库这件事搞明白。

相关推荐
Lyra_Infra1 小时前
从 MySQL 到达梦:一次信创隔离环境里的数据库迁移踩坑实录
数据库·后端·mysql
数安3000天2 小时前
数据分类分级产品有哪四类技术路线?
大数据·数据库
泡茶喝茶写代码2 小时前
量化数据开发实战系列(第 25 篇):基金基础接口实战:基金列表、ETF-LOF 分类、基金概况、净值数据
java·数据库·人工智能·python·mysql
张小姐的猫2 小时前
【AI大模型接入SDK】 —— 数据管理 & 与Session模块进行联动
数据结构·数据库·c++·人工智能·python·chatgpt
IvorySQL2 小时前
PostgreSQL 日报|大模型破解在线校验和(9 月 15 日)
数据库·人工智能·postgresql
Leon-Ning Liu3 小时前
Oracle 19c ASMB 进程 PGA 内存泄漏排查实战 (Bug 38610635)
数据库·oracle
步行cgn3 小时前
Spring 注入 null 和空字符串详解
数据库·spring·oracle
Allen_LVyingbo3 小时前
医疗人工智能项目全生命周期管理系统:监管知识建模、工程实现与实证评估(下)
大数据·数据库·人工智能·python·自然语言处理·自动化
草莓熊Lotso3 小时前
【Redis 进阶】主从复制深度解析:从配置落地到 PSYNC 同步原理
linux·开发语言·网络·数据库·redis·缓存·php