第三章:基础用法
第三章:基础用法
3.1 命令基本语法
Sysbench 1.0.x 的命令遵循以下语法结构:
sysbench [选项]... 测试名称 命令
3.1.1 三要素
sysbench ←→ [选项] ←→ 测试名称 ←→ 命令
工具 参数 测试类型 操作
示例拆解:
sysbench --threads=4 --time=60 cpu run
│ │ │ │
│ │ │ └─ 命令:run / prepare / cleanup / help
│ │ └───── 测试名称:cpu / memory / fileio / oltp_read_write ...
│ └────────────────────────── 选项:--threads、--time 等
└──────────────────────────────────── 工具名
3.1.2 命令类型
| 命令 | 说明 | 适用场景 |
|---|---|---|
prepare | 准备测试数据 | 数据库:创建表和数据;文件 I/O:创建测试文件 |
run | 执行测试 | 所有测试类型 |
cleanup | 清理测试数据 | 数据库:删除测试表;文件 I/O:删除测试文件 |
help | 显示测试的帮助信息 | 查看特定测试的选项 |
3.2 查看可用测试
# 列出所有内置测试
sysbench --list-tests
# 查看特定测试的帮助
sysbench cpu help
sysbench oltp_read_write help
sysbench memory help
sysbench fileio help
输出示例(–list-tests):
Available tests:
fileio - File I/O test
cpu - CPU performance test
memory - Memory functions speed test
threads - Threads subsystem performance test
mutex - Mutex performance test
oltp_read_write - OLTP read-write benchmark
oltp_read_only - OLTP read-only benchmark
oltp_write_only - OLTP write-only benchmark
oltp_insert - OLTP insert benchmark
oltp_update_index - OLTP update index benchmark
oltp_update_non_index - OLTP update non-index benchmark
oltp_delete - OLTP delete benchmark
oltp_point_select - OLTP point select benchmark
oltp_begin_commit - OLTP begin/commit benchmark
oltp_begin_rollback - OLTP begin/rollback benchmark
3.3 通用选项
3.3.1 线程与并发
| 选项 | 默认值 | 说明 |
|---|---|---|
--threads=N | 1 | 工作线程数 |
--thread-locks=N | 8 | 每个线程持有的锁数量 |
--thread-stack-size=SIZE | 64K | 每个线程的栈大小 |
# 使用 8 个线程
sysbench cpu --threads=8 run
# 每线程 16 个锁
sysbench mutex --threads=4 --thread-locks=16 run
3.3.2 测试时长与迭代
| 选项 | 默认值 | 说明 |
|---|---|---|
--time=N | 10 | 测试持续时间(秒),0 表示不限时 |
--events=N | 0 | 最大事件数,0 表示不限 |
--forced-shutdown=STRING | off | 超时后强制关闭(如 --forced-shutdown=30s) |
# 运行 60 秒
sysbench cpu --time=60 run
# 运行 10000 个事件后停止
sysbench cpu --events=10000 run
# 运行 5 分钟,超时后 30 秒内强制关闭
sysbench cpu --time=300 --forced-shutdown=30s run
最佳实践:
--time建议至少设置为 60 秒,正式测试建议 300 秒(5 分钟)以上,以获得稳定的结果。
3.3.3 随机数生成
| 选项 | 默认值 | 说明 |
|---|---|---|
--rand-type=STRING | special | 随机数分布类型:uniform / gaussian / special / zipfian |
--rand-seed=N | 0 | 随机数种子(0 = 使用当前时间) |
--rand-spec-pct=N | 1 | special 分布中 “热点” 数据占比 |
--rand-spec-res=N | 75 | special 分布中热点数据的百分比 |
--rand-pareto-h=N | 0.2 | Pareto 分布的形状参数 |
--rand-zipfian-exp=N | 0.8 | Zipfian 分布的指数参数 |
# 使用均匀分布
sysbench oltp_read_write --rand-type=uniform run
# 使用高斯分布
sysbench oltp_read_write --rand-type=gaussian run
# 使用 Zipfian 分布(热点数据集中访问)
sysbench oltp_read_write --rand-type=zipfian run
分布类型说明:
uniform gaussian zipfian
┌───┐ ┌─┐ ┌─┐
│ │ │ │ │ │
│ │ ┌┤ ├┐ │ ├──┐
│ │ ┌┤│ ││┐ ┌┤│ │┐
│ │ ┌┤││ │││┐ ┌┤││ ││┐
├─────────── ├───────── ├──────────
均匀分布 钟形分布 长尾分布(热点集中)
3.3.4 输出与报告
| 选项 | 默认值 | 说明 |
|---|---|---|
--verbosity=N | 3 | 输出详细级别(0=silent, 3=默认, 5=debug) |
--percentile=N | 95 | 延迟百分位数(可设置为 99) |
--histogram[=on/off] | off | 输出延迟直方图 |
--csv[=FILE] | - | 输出 CSV 格式结果 |
--json[=FILE] | - | 输出 JSON 格式结果 |
# 输出 P99 延迟
sysbench cpu --percentile=99 --time=60 run
# 启用延迟直方图
sysbench cpu --histogram --time=60 run
# 输出 CSV 文件
sysbench cpu --csv=result.csv --time=60 run
# 输出 JSON 文件
sysbench cpu --json=result.json --time=60 run
# 安静模式(只输出最终结果)
sysbench cpu --verbosity=0 --time=60 run
3.3.5 数据库通用选项
| 选项 | 默认值 | 说明 |
|---|---|---|
--db-driver=STRING | mysql | 数据库驱动:mysql / pgsql / sqlite3 |
--db-ps-mode=STRING | auto | 预编译语句模式:auto / disable |
--db-debug[=on/off] | off | 输出数据库调试信息 |
3.3.6 MySQL 连接选项
| 选项 | 默认值 | 说明 |
|---|---|---|
--mysql-host=STRING | 127.0.0.1 | MySQL 主机 |
--mysql-port=N | 3306 | MySQL 端口 |
--mysql-user=STRING | root | 用户名 |
--mysql-password=STRING | - | 密码 |
--mysql-db=STRING | sbtest | 测试数据库名 |
--mysql-socket=STRING | - | Unix Socket 路径 |
--mysql-ssl[=on/off] | off | 启用 SSL 连接 |
3.3.7 PostgreSQL 连接选项
| 选项 | 默认值 | 说明 |
|---|---|---|
--pgsql-host=STRING | 127.0.0.1 | PostgreSQL 主机 |
--pgsql-port=N | 5432 | PostgreSQL 端口 |
--pgsql-user=STRING | root | 用户名 |
--pgsql-password=STRING | - | 密码 |
--pgsql-db=STRING | sbtest | 测试数据库名 |
3.4 输出结果详解
以 sysbench cpu --threads=4 --time=10 run 为例,逐行解读输出:
sysbench 1.0.20 (using bundled Lua JIT) ← 版本信息
Running the test with following options: ← 测试配置
Number of threads: 4 ← 线程数
Initializing random number generator from current time
Prime numbers limit: 10000 ← CPU 测试:素数上限
Initializing worker threads...
Threads started!
CPU speed: ← 【CPU 性能指标】
events per second: 5678.90 ← 每秒完成的事件数(核心指标)
General statistics: ← 【总体统计】
total time: 10.0012s ← 实际运行时长
total number of events: 56801 ← 总完成事件数
Latency (ms): ← 【延迟分布】
min: 0.68 ← 最小延迟
avg: 0.70 ← 平均延迟
max: 3.45 ← 最大延迟
95th percentile: 0.73 ← P95 延迟(95% 的请求低于此值)
sum: 7000.84 ← 总延迟
Threads fairness: ← 【线程公平性】
events (avg/stddev): 14200.2500/12.34 ← 每线程平均事件数/标准差
execution time (avg/stddev): 2.5003/0.00 ← 每线程平均执行时间/标准差
3.4.1 关键指标解读
| 指标 | 含义 | 如何判断好坏 |
|---|---|---|
| events per second | 吞吐量 | 越高越好,用于对比不同环境 |
| avg latency | 平均延迟 | 越低越好,反映整体响应速度 |
| 95th percentile | P95 延迟 | 最重要的延迟指标,反映尾部延迟 |
| max latency | 最大延迟 | 关注异常值,偶尔偏高可接受 |
| stddev (公平性) | 标准差 | 越小越好,说明各线程负载均衡 |
3.4.2 延迟直方图解读
启用 --histogram 后会输出延迟分布直方图:
Latency histogram (ms):
value | count | distribution
0.600 | 89 | ██████
0.700 | 12456 | ████████████████████████████████████████
0.800 | 15234 | ██████████████████████████████████████████████████
0.900 | 8901 | █████████████████████████████
1.000 | 4567 | ███████████████
1.500 | 2345 | ████████
2.000 | 890 | ███
3.000 | 123 | █
5.000 | 12 |
10.000 | 2 |
- 集中度:大部分值应集中在较低区间
- 长尾:关注是否有明显的长尾分布(可能表明偶发性卡顿)
- 方差:分布越集中,性能越稳定
3.5 通用测试流程
3.5.1 四步标准流程
对于数据库和文件 I/O 测试,遵循 准备 → 预热 → 正式测试 → 清理 的四步流程:
# ====== 步骤 1:准备测试数据 ======
sysbench oltp_read_write \
--mysql-host=127.0.0.1 \
--mysql-user=root \
--mysql-password=secret \
--tables=16 \
--table-size=1000000 \
prepare
# ====== 步骤 2:预热(可选但推荐) ======
sysbench oltp_read_write \
--mysql-host=127.0.0.1 \
--mysql-user=root \
--mysql-password=secret \
--tables=16 \
--table-size=1000000 \
--threads=8 \
--time=30 \
run
# 预热结果可忽略
# ====== 步骤 3:正式测试 ======
sysbench oltp_read_write \
--mysql-host=127.0.0.1 \
--mysql-user=root \
--mysql-password=secret \
--tables=16 \
--table-size=1000000 \
--threads=16 \
--time=300 \
--histogram \
--percentile=99 \
run
# ====== 步骤 4:清理测试数据 ======
sysbench oltp_read_write \
--mysql-host=127.0.0.1 \
--mysql-user=root \
--mysql-password=secret \
--tables=16 \
cleanup
3.5.2 CPU / 内存测试流程
CPU 和内存测试不需要 prepare/cleanup:
# CPU 测试(直接 run)
sysbench cpu --threads=8 --time=60 run
# 内存测试(直接 run)
sysbench memory --threads=4 --time=60 run
3.6 参数调优建议
3.6.1 线程数设置
| 场景 | 建议线程数 | 原因 |
|---|---|---|
| CPU 基准测试 | = CPU 核心数 | 评估 CPU 满载性能 |
| CPU 扩展性测试 | 1, 2, 4, 8, 16, … | 观察多核扩展性 |
| 数据库 OLTP | 数据库连接数的 50%-100% | 模拟并发连接 |
| 文件 I/O | 磁盘队列深度 × 2 | 充分利用 I/O 能力 |
| 内存测试 | = CPU 核心数 | 避免总线争用干扰 |
# 渐进式线程数测试脚本
for threads in 1 2 4 8 16 32 64; do
echo "=== Testing with $threads threads ==="
sysbench oltp_read_write \
--mysql-host=127.0.0.1 \
--mysql-user=root \
--tables=16 \
--table-size=1000000 \
--threads=$threads \
--time=60 \
run 2>&1 | grep -E "transactions|queries|avg|95th"
echo ""
done
3.6.2 测试时长设置
| 场景 | 建议时长 | 说明 |
|---|---|---|
| 快速验证 | 10-30 秒 | 检查配置是否正确 |
| 开发调试 | 60 秒 | 获取初步结果 |
| 正式测试 | 300 秒 | 获取稳定的统计数据 |
| 长期稳定性测试 | 3600+ 秒 | 发现内存泄漏、性能衰减 |
3.6.3 数据量设置
数据库测试的数据量直接影响缓存命中率:
| 数据量 vs 内存 | 场景 | 说明 |
|---|---|---|
| 数据集 < Buffer Pool | 纯缓存测试 | 所有数据在内存中,测的是 CPU + 内存 |
| 数据集 ≈ Buffer Pool | 混合测试 | 接近真实场景 |
| 数据集 > Buffer Pool | 磁盘 I/O 测试 | 会产生大量磁盘 I/O |
# 估算数据量(MySQL InnoDB)
# 假设每行约 250 字节,100万行 ≈ 250MB
# 16 张表 × 100万行 ≈ 4GB
# 如果 Buffer Pool 为 8GB,则数据集 ≈ Buffer Pool 的 50%
# 生成大于 Buffer Pool 的数据集(测试磁盘 I/O)
sysbench oltp_read_write \
--mysql-host=127.0.0.1 \
--mysql-user=root \
--tables=64 \
--table-size=10000000 \
prepare
3.7 脚本化测试
3.7.1 批量测试脚本
#!/bin/bash
# bench_all.sh - 全面基准测试脚本
set -euo pipefail
MYSQL_HOST="127.0.0.1"
MYSQL_USER="root"
MYSQL_PASS="secret"
DB_NAME="sbtest"
TABLES=16
TABLE_SIZE=1000000
DURATION=300
THREADS_LIST="1 2 4 8 16 32"
RESULT_DIR="./bench_results_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$RESULT_DIR"
echo "========================================="
echo "Sysbench 全面基准测试"
echo "时间: $(date)"
echo "结果目录: $RESULT_DIR"
echo "========================================="
# 准备数据
echo ">>> 准备测试数据..."
sysbench oltp_read_write \
--mysql-host=$MYSQL_HOST \
--mysql-user=$MYSQL_USER \
--mysql-password=$MYSQL_PASS \
--mysql-db=$DB_NAME \
--tables=$TABLES \
--table-size=$TABLE_SIZE \
prepare
# 预热
echo ">>> 预热..."
sysbench oltp_read_write \
--mysql-host=$MYSQL_HOST \
--mysql-user=$MYSQL_USER \
--mysql-password=$MYSQL_PASS \
--mysql-db=$DB_NAME \
--tables=$TABLES \
--table-size=$TABLE_SIZE \
--threads=8 \
--time=30 \
run > /dev/null 2>&1
# 执行不同线程数的测试
for test in oltp_read_write oltp_read_only oltp_point_select oltp_update_index; do
echo ""
echo ">>> 测试: $test"
for threads in $THREADS_LIST; do
echo " -> 线程数: $threads"
result_file="$RESULT_DIR/${test}_t${threads}.json"
sysbench $test \
--mysql-host=$MYSQL_HOST \
--mysql-user=$MYSQL_USER \
--mysql-password=$MYSQL_PASS \
--mysql-db=$DB_NAME \
--tables=$TABLES \
--table-size=$TABLE_SIZE \
--threads=$threads \
--time=$DURATION \
--histogram \
--percentile=99 \
--json=$result_file \
run
sleep 5 # 间隔等待
done
done
# 清理
echo ""
echo ">>> 清理测试数据..."
sysbench oltp_read_write \
--mysql-host=$MYSQL_HOST \
--mysql-user=$MYSQL_USER \
--mysql-password=$MYSQL_PASS \
--mysql-db=$DB_NAME \
--tables=$TABLES \
cleanup
echo ""
echo "========================================="
echo "测试完成!结果保存在: $RESULT_DIR"
echo "========================================="
3.7.2 结果收集脚本
#!/bin/bash
# parse_results.sh - 解析 JSON 结果
RESULT_DIR=$1
echo "测试类型,线程数,TPS,QPS,P95延迟(ms)"
for f in "$RESULT_DIR"/*.json; do
test_name=$(basename "$f" | sed 's/_t[0-9]*\.json//')
threads=$(basename "$f" | grep -oP 't\K[0-9]+')
tps=$(jq '.transactions.per_second' "$f")
qps=$(jq '.queries.per_second' "$f")
p95=$(jq '.latency.percentiles["95th"]' "$f")
echo "$test_name,$threads,$tps,$qps,$p95"
done
3.8 输出格式详解
3.8.1 CSV 输出
sysbench cpu --csv=cpu_result.csv --time=60 run
CSV 文件包含以下列:
time,transactions,queries,read,write,other,errors,reconnects,time_interval,total_time,total_events,percentile_95,percentile_99
1,2345,12345,6789,3456,2100,0,0,1.0006,1.0006,2345,0.73,0.89
2,2367,12456,6812,3489,2155,0,0,1.0003,2.0009,4712,0.74,0.91
...
3.8.2 JSON 输出
sysbench cpu --json=cpu_result.json --time=60 run
JSON 结构:
{
"sysbench_version": "1.0.20",
"threads": 4,
"cpu_speed": {
"events_per_second": 5678.90
},
"general": {
"total_time": 60.0012,
"total_events": 340734
},
"latency": {
"min": 0.68,
"avg": 0.70,
"max": 3.45,
"percentile_95": 0.73,
"percentile_99": 0.89,
"sum": 42001.34
},
"threads_fairness": {
"events": {
"avg": 85183.5,
"stddev": 12.34
},
"execution_time": {
"avg": 10.0003,
"stddev": 0.00
}
}
}
3.8.3 使用 jq 解析 JSON 结果
# 提取 TPS
jq '.cpu_speed.events_per_second' cpu_result.json
# 提取 P95 延迟
jq '.latency.percentile_95' cpu_result.json
# 格式化输出所有关键指标
jq '{
tps: .cpu_speed.events_per_second,
total_time: .general.total_time,
avg_latency: .latency.avg,
p95_latency: .latency.percentile_95
}' cpu_result.json
3.9 环境变量支持
Sysbench 也支持通过环境变量传递参数(大写形式,前缀 SYSBENCH_):
# 通过环境变量设置
export SYSBENCH_THREADS=8
export SYSBENCH_TIME=60
export SYSBENCH_MYSQL_HOST=127.0.0.1
export SYSBENCH_MYSQL_USER=root
export SYSBENCH_MYSQL_PASSWORD=secret
# 运行测试
sysbench oltp_read_write --tables=16 --table-size=1000000 run
注意:命令行参数优先级高于环境变量。
3.10 常见错误及解决
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
FATAL: Unable to connect to MySQL server | 数据库连接失败 | 检查主机、端口、用户名、密码 |
FATAL: mysql_stmt_execute() returned error | SQL 执行错误 | 检查数据库权限、表是否存在 |
FATAL: Cannot open file | 文件 I/O 错误 | 检查磁盘空间和权限 |
Unknown test: xxx | 测试名称错误 | 使用 --list-tests 查看可用测试 |
FATAL: pthread_create() failed | 线程创建失败 | 减少线程数或增加系统限制 |
# 检查系统线程限制
ulimit -u
# 增加限制
ulimit -u 65535
# 检查 MySQL 连接
mysql -h 127.0.0.1 -u root -p -e "SELECT 1"
# 检查最大连接数
mysql -e "SHOW VARIABLES LIKE 'max_connections'"
3.11 小结
| 要点 | 说明 |
|---|---|
| 命令结构 | sysbench [选项] 测试名 命令 |
| 三个命令 | prepare / run / cleanup |
| 关键选项 | --threads、--time、--histogram、--percentile |
| 标准流程 | 准备 → 预热 → 正式测试 → 清理 |
| 输出格式 | 文本(默认)/ CSV / JSON |
| 核心指标 | TPS(吞吐量)、P95 延迟(尾部延迟) |