sysbench数据库压测完全指南:从安装到结果分析
前言
在数据库运维和开发过程中,性能测试是必不可少的环节。sysbench作为一款开源、多线程的基准测试工具,已经成为业界数据库性能评估的标准工具之一。本文将详细介绍如何使用sysbench对MySQL数据库进行压力测试,包括环境搭建、参数配置、测试执行以及结果分析,并提供完整的测试脚本和结果解读方法。
一、sysbench简介
sysbench是一个模块化、跨平台的多线程基准测试工具,主要用于评估系统性能,特别适用于数据库性能测试。它的主要特性包括:
- 多用途:可用于测试CPU、内存、文件I/O、线程和数据库性能
- 跨平台:支持Linux、Windows、macOS等操作系统
- 模块化设计:不同测试项目通过不同模块实现
- Lua脚本支持:可灵活自定义测试逻辑
- 支持多种数据库:MySQL、PostgreSQL、达梦等
常用测试模型
sysbench通过Lua脚本定义了多种压测模型:
| 测试模型 | 描述 |
|---|---|
| oltp_read_write.lua | 混合读写测试,模拟真实OLTP场景 |
| oltp_read_only.lua | 只读测试 |
| oltp_write_only.lua | 只写测试 |
| insert.lua | 单值插入测试 |
| delete.lua | 删除测试 |
| bulk_insert.lua | 批量插入测试 |
二、环境准备
2.1 测试环境说明
本文的测试环境如下:
| 配置项 | 参数 |
|---|---|
| 压测机OS | CentOS 7.5 |
| 压测机规格 | 4核8G |
| 数据库 | MySQL 8.0.25 |
| 数据库规格 | 4核16G |
| sysbench版本 | 1.0.20 |
注意:不同服务器配置会导致测试结果差异很大,本文结果仅供参考。
2.2 安装sysbench
方法一:YUM安装(推荐)
# 下载官方仓库脚本
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
# 安装sysbench
sudo yum -y install sysbench
# 查看版本
sysbench --version
方法二:源码编译安装
如果需要最新版本或特定功能,可以选择源码编译:
# 下载源码
git clone https://github.com/akopytov/sysbench.git
cd sysbench
git checkout 1.0.20
# 安装依赖
yum install -y gcc gcc-c++ autoconf automake make libtool mysql-devel
# 编译安装
./autogen.sh
./configure
make -j
make install
# 验证安装
sysbench --version
2.3 准备测试数据库
在MySQL中创建用于压测的数据库和用户:
-- 创建测试数据库
CREATE DATABASE IF NOT EXISTS sbtest;
-- 创建压测用户
CREATE USER 'sbtest'@'%' IDENTIFIED WITH mysql_native_password BY 'sbtest123';
-- 授予权限
GRANT ALL PRIVILEGES ON sbtest.* TO 'sbtest'@'%';
FLUSH PRIVILEGES;
三、压测脚本详解
3.1 基础参数说明
sysbench压测命令的核心参数分类如下:
数据库连接参数
| 参数 | 说明 | 示例 |
|---|---|---|
--db-driver |
数据库驱动类型 | mysql |
--mysql-host |
MySQL服务器地址 | 192.168.1.100 |
--mysql-port |
MySQL端口 | 3306 |
--mysql-user |
数据库用户名 | sbtest |
--mysql-password |
数据库密码 | sbtest123 |
--mysql-db |
测试数据库名 | sbtest |
测试负载参数
| 参数 | 说明 | 示例 |
|---|---|---|
--tables |
测试表数量 | 10 |
--table_size |
每张表的行数 | 1000000 |
--threads |
并发线程数 | 16 |
--time |
测试持续时间(秒) | 300 |
--report-interval |
报告输出间隔(秒) | 1 |
--percentile |
百分位数 | 95 |
测试类型与阶段
| 阶段 | 说明 |
|---|---|
prepare |
准备测试数据 |
run |
执行压测 |
cleanup |
清理测试数据 |
3.2 准备测试数据
在执行压测前,需要先准备测试数据:
sysbench \
--db-driver=mysql \
--mysql-host=192.168.1.100 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-password='sbtest123' \
--mysql-db=sbtest \
--tables=10 \
--table_size=1000000 \
--threads=16 \
--time=0 \
oltp_read_write \
prepare
执行成功后,会在数据库中创建10张以sbtest开头的表,每张表包含100万条测试数据。
3.3 执行压测
数据准备完成后,执行压测命令:
sysbench \
--db-driver=mysql \
--mysql-host=192.168.1.100 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-password='sbtest123' \
--mysql-db=sbtest \
--tables=10 \
--table_size=1000000 \
--threads=16 \
--time=300 \
--report-interval=10 \
--percentile=95 \
oltp_read_write \
run
3.4 清理测试数据
测试完成后,可以清理数据:
sysbench \
--db-driver=mysql \
--mysql-host=192.168.1.100 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-password='sbtest123' \
--mysql-db=sbtest \
--tables=10 \
oltp_read_write \
cleanup
四、压测结果解读
4.1 实时输出解读
压测过程中,每10秒会输出一次实时结果:
[ 10s ] thds: 16 tps: 412.35 qps: 8247.00 (r/w/o: 5772.90/1649.40/824.70) lat (ms,95%): 45.23 err/s: 0.00 reconn/s: 0.00
各字段含义:
| 字段 | 说明 |
|---|---|
| thds: 16 | 当前并发线程数 |
| tps: 412.35 | 每秒处理事务数 |
| qps: 8247.00 | 每秒处理请求数 |
| r/w/o | 读/写/其他请求数 |
| lat (ms,95%) | 95%请求的延迟 |
| err/s | 每秒错误数 |
| reconn/s | 每秒重连次数 |
4.2 最终结果解读
压测结束后,sysbench会输出完整的统计报告:
SQL statistics:
queries performed:
read: 115864 # 读请求总数
write: 33104 # 写请求总数
other: 16552 # 其他请求数
total: 165520 # 总请求数
transactions: 8276 (823.13 per sec.) # 事务数及TPS
queries: 165520 (16462.75 per sec.) # 查询数及QPS
ignored errors: 0 (0.00 per sec.)
reconnects: 0 (0.00 per sec.)
General statistics:
total time: 10.0543s # 总耗时
total number of events: 8276 # 总事件数
Latency (ms):
min: 4.22 # 最小延迟
avg: 12.10 # 平均延迟
max: 172.82 # 最大延迟
95th percentile: 18.28 # 95分位延迟
sum: 100141.94
Threads fairness:
events (avg/stddev): 827.6000/87.15 # 线程事件分布
execution time (avg/stddev): 10.0142/0.02 # 线程执行时间分布
4.3 关键指标说明
| 指标 | 含义 | 重要性 |
|---|---|---|
| TPS | 每秒事务数 | ⭐⭐⭐⭐⭐ 核心指标 |
| QPS | 每秒查询数 | ⭐⭐⭐⭐⭐ 核心指标 |
| 平均延迟 | 所有请求的平均响应时间 | ⭐⭐⭐⭐ |
| 95分位延迟 | 95%的请求都在此时间内完成 | ⭐⭐⭐⭐⭐ 最重要 |
| 错误率 | 出错请求占比 | ⭐⭐⭐⭐⭐ |
| 线程公平性 | 各线程负载是否均衡 | ⭐⭐⭐ |
五、完整压测脚本
5.1 单次测试脚本
#!/bin/bash
# single_test.sh - 单次sysbench压测脚本
# 数据库连接配置
DB_HOST="192.168.1.100"
DB_PORT="3306"
DB_USER="sbtest"
DB_PASS="sbtest123"
DB_NAME="sbtest"
# 测试配置
TABLES=10
TABLE_SIZE=1000000
THREADS=16
TEST_TIME=300
REPORT_INTERVAL=10
# 测试类型
TEST_TYPE="oltp_read_write"
echo "========== 开始准备测试数据 =========="
sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
--table_size=${TABLE_SIZE} \
--threads=${THREADS} \
${TEST_TYPE} prepare
if [ $? -eq 0 ]; then
echo "========== 数据准备完成,开始压测 =========="
sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
--table_size=${TABLE_SIZE} \
--threads=${THREADS} \
--time=${TEST_TIME} \
--report-interval=${REPORT_INTERVAL} \
--percentile=95 \
${TEST_TYPE} run
else
echo "数据准备失败,请检查配置"
exit 1
fi
echo "========== 压测完成,清理数据 =========="
sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
${TEST_TYPE} cleanup
5.2 多线程并发测试脚本
为了全面评估数据库性能,建议测试不同并发数下的表现:
#!/bin/bash
# multi_thread_test.sh - 多线程梯度压测脚本
DB_HOST="192.168.1.100"
DB_PORT="3306"
DB_USER="sbtest"
DB_PASS="sbtest123"
DB_NAME="sbtest"
TABLES=10
TABLE_SIZE=1000000
TEST_TIME=180
REPORT_INTERVAL=10
# 测试线程数梯度
THREADS_LIST=(4 8 16 32 64 128)
# 结果文件
RESULT_FILE="test_results_$(date +%Y%m%d_%H%M%S).txt"
echo "========== Sysbench 压测结果报告 ==========" > ${RESULT_FILE}
echo "测试时间: $(date)" >> ${RESULT_FILE}
echo "数据库: ${DB_HOST}:${DB_PORT}" >> ${RESULT_FILE}
echo "测试配置: ${TABLES}张表 x ${TABLE_SIZE}行数据" >> ${RESULT_FILE}
echo "测试时长: ${TEST_TIME}秒" >> ${RESULT_FILE}
echo "=========================================" >> ${RESULT_FILE}
printf "%-8s %-12s %-12s %-12s %-12s\n" "Threads" "TPS" "QPS" "Avg Lat(ms)" "95% Lat(ms)" >> ${RESULT_FILE}
# 准备数据(仅执行一次)
echo "准备测试数据..."
sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
--table_size=${TABLE_SIZE} \
--threads=16 \
oltp_read_write prepare
# 循环测试不同线程数
for THREADS in ${THREADS_LIST[@]}; do
echo "正在测试 ${THREADS} 线程..."
# 执行压测并提取关键指标
RESULT=$(sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
--table_size=${TABLE_SIZE} \
--threads=${THREADS} \
--time=${TEST_TIME} \
--report-interval=10 \
--percentile=95 \
oltp_read_write run 2>&1)
# 提取TPS
TPS=$(echo "$RESULT" | grep "transactions:" | awk -F'(' '{print $2}' | awk '{print $1}')
# 提取QPS
QPS=$(echo "$RESULT" | grep "queries:" | awk -F'(' '{print $2}' | awk '{print $1}')
# 提取平均延迟
AVG_LAT=$(echo "$RESULT" | grep "avg:" | awk '{print $2}')
# 提取95分位延迟
P95_LAT=$(echo "$RESULT" | grep "95th percentile:" | awk '{print $3}')
printf "%-8s %-12s %-12s %-12s %-12s\n" \
"${THREADS}" "${TPS}" "${QPS}" "${AVG_LAT}" "${P95_LAT}" >> ${RESULT_FILE}
echo " ${THREADS} 线程测试完成: TPS=${TPS}, QPS=${QPS}"
# 每个线程数测试后等待30秒,让数据库恢复
sleep 30
done
# 清理数据
echo "清理测试数据..."
sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
oltp_read_write cleanup
echo "测试完成!结果已保存至 ${RESULT_FILE}"
cat ${RESULT_FILE}
5.3 不同测试类型脚本
#!/bin/bash
# multi_test_type.sh - 不同测试类型对比脚本
DB_HOST="192.168.1.100"
DB_PORT="3306"
DB_USER="sbtest"
DB_PASS="sbtest123"
DB_NAME="sbtest"
TABLES=10
TABLE_SIZE=500000
THREADS=32
TEST_TIME=120
# 测试类型列表
TEST_TYPES=("oltp_read_only" "oltp_write_only" "oltp_read_write")
echo "========== 不同测试类型性能对比 =========="
printf "%-20s %-12s %-12s %-12s\n" "测试类型" "TPS" "QPS" "95% Lat(ms)"
echo "----------------------------------------"
for TEST_TYPE in ${TEST_TYPES[@]}; do
echo "准备 ${TEST_TYPE} 测试数据..."
sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
--table_size=${TABLE_SIZE} \
--threads=${THREADS} \
${TEST_TYPE} prepare > /dev/null 2>&1
echo "执行 ${TEST_TYPE} 压测..."
RESULT=$(sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
--table_size=${TABLE_SIZE} \
--threads=${THREADS} \
--time=${TEST_TIME} \
--percentile=95 \
${TEST_TYPE} run 2>&1)
TPS=$(echo "$RESULT" | grep "transactions:" | awk -F'(' '{print $2}' | awk '{print $1}')
QPS=$(echo "$RESULT" | grep "queries:" | awk -F'(' '{print $2}' | awk '{print $1}')
P95_LAT=$(echo "$RESULT" | grep "95th percentile:" | awk '{print $3}')
printf "%-20s %-12s %-12s %-12s\n" "${TEST_TYPE}" "${TPS}" "${QPS}" "${P95_LAT}"
# 清理数据
sysbench --db-driver=mysql \
--mysql-host=${DB_HOST} \
--mysql-port=${DB_PORT} \
--mysql-user=${DB_USER} \
--mysql-password="${DB_PASS}" \
--mysql-db=${DB_NAME} \
--tables=${TABLES} \
${TEST_TYPE} cleanup > /dev/null 2>&1
sleep 30
done
六、压测结果示例
6.1 不同并发数测试结果
以下是在4核16G MySQL、4核8G压测机环境下的测试结果:
| 线程数 | TPS | QPS | 平均延迟(ms) | 95%延迟(ms) |
|---|---|---|---|---|
| 4 | 215 | 4300 | 18.5 | 32.1 |
| 8 | 380 | 7600 | 21.0 | 45.2 |
| 16 | 412 | 8247 | 23.5 | 52.8 |
| 32 | 385 | 7700 | 83.0 | 142.5 |
| 64 | 338 | 6760 | 189.0 | 324.6 |
从结果可以看出:
- 在16线程时达到性能峰值(TPS约412)
- 超过最优并发数后,TPS开始下降,延迟显著增加
- 数据库的瓶颈大约在16-32并发之间
6.2 不同规格数据库对比
参考云厂商的基准测试数据,不同规格数据库的性能表现:
| 数据库规格 | 线程数 | QPS | TPS | 95%延迟(ms) |
|---|---|---|---|---|
| 4核8G | 32 | 35917 | 1795 | 17.82 |
| 8核32G | 64 | 67719 | 3385 | 18.90 |
| 16核128G | 128 | 127955 | 6397 | 20.00 |
七、压测注意事项
7.1 环境要求
- 压测机配置:压测机配置应不低于数据库配置,避免压测机成为瓶颈
- 网络延迟:确保压测机与数据库在同一可用区,网络延迟影响测试准确性
- 数据量设置:测试数据量应至少为内存的1.2倍,确保数据不能完全缓存在内存中
7.2 测试建议
- 预热数据库:正式压测前先进行1-2分钟预热,让数据库缓存预热
- 多次测试取平均:每个参数组合建议测试3次取平均值
- 监控系统资源:压测时同时监控CPU、内存、磁盘IO、网络等指标
- 逐步增加压力:从低并发开始逐步增加,找到性能拐点
7.3 常见问题
Q: 压测时出现连接错误?
A: 检查MySQL的max_connections参数,适当调大该值。
Q: 延迟突然飙升?
A: 可能是达到数据库瓶颈,检查CPU、内存、磁盘IO使用率。
Q: TPS/QPS不稳定?
A: 检查是否有其他进程占用资源,或网络波动。
八、总结
sysbench作为业界标准的数据库压测工具,能够有效评估数据库在不同负载下的性能表现。通过本文的详细指南,你可以:
- 快速部署:使用YUM或源码方式安装sysbench
- 灵活配置:根据不同测试需求调整参数
- 自动化测试:使用提供的脚本进行梯度压测
- 科学分析:理解各项指标含义,准确评估数据库性能
压测是数据库性能优化的基础,建议在以下场景进行压测:
- 新上线系统评估容量
- 数据库版本升级前验证
- 参数调优效果验证
- 架构改造前后对比
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)