容器中运行sysbench压测mysql需解决网络隔离、权限配置、性能参数优化、缓冲池设置、连接管理及环境一致性五大问题:开放3306端口、创建远程用户、使用宿主机ip或网络别名;关闭performance_schema等非必要项;合理设置innodb_buffer_pool_size;调大thread_cache_size并检查ulimit;确保时区、字符集、sql mode与生产一致。

容器里跑 sysbench,得先解决网络和权限问题
直接在宿主机上用 sysbench 连容器里的 MySQL,默认会失败——不是密码错,而是容器网络隔离导致连接被拒或超时。常见报错是 Can't connect to MySQL server on '127.0.0.1' 或 Connection refused。
必须确认三点:
- MySQL 容器暴露了
3306端口(docker run -p 3306:3306或docker-compose.yml中有ports声明) - MySQL 用户允许远程连接:
CREATE USER 'sbtest'@'%' IDENTIFIED BY 'pass123'; GRANT ALL ON sbtest.* TO 'sbtest'@'%'; FLUSH PRIVILEGES; -
sysbench命令里不能写localhost,得用宿主机 IP(如--mysql-host=172.16.10.5)或 Docker 网络别名(如--mysql-host=mysql,前提是两者在同一自定义 bridge 网络)
用 docker-compose 启动 MySQL + 挂载配置,避免默认参数拖慢压测
默认的 MySQL 容器镜像(如 mysql:8.0)启用了严格模式、慢查询日志、performance_schema 全开——这些对压测干扰极大,尤其 performance_schema 在高并发下会显著拉低 TPS。
建议在 docker-compose.yml 中显式关闭非必要项:
services:
mysql:
image: mysql:8.0
command: >
--skip-performance-schema
--innodb-flush-log-at-trx-commit=2
--sync-binlog=0
--max-connections=2048
environment:
MYSQL_ROOT_PASSWORD: rootpass
volumes:
- ./my.cnf:/etc/mysql/conf.d/custom.cnf:ro
my.cnf 内容示例:
[mysqld] innodb_buffer_pool_size = 2G innodb_log_file_size = 256M table_open_cache = 4000 skip_log_bin
注意:innodb_flush_log_at_trx_commit=2 和 sync_binlog=0 仅用于压测环境,生产严禁使用。
sysbench prepare 阶段卡住?检查容器磁盘 I/O 和 buffer pool 是否足够
执行 sysbench oltp_read_write.lua ... prepare 时如果长时间无响应,大概率不是网络问题,而是容器内 MySQL 的 innodb_buffer_pool_size 设置过小,导致大量刷脏页 + 磁盘争用。
典型表现:
- 宿主机
iostat -x 1显示%util接近 100%,await> 50ms - MySQL 容器内
SHOW ENGINE INNODB STATUS\G中出现大量Buffer pool hit rate -
docker stats显示 MySQL 容器内存使用率持续 > 90%
解决办法:
- 确保
innodb_buffer_pool_size至少设为容器内存限制的 60%~75%(例如容器内存限制4g,则该值设为2.5g) - prepare 阶段前加
--tables=4 --table-size=500000控制数据量,避免单表过大触发频繁 checkpoint - 若用 SSD,可在
docker run中加--device-read-iops/--device-write-iops限速,反向验证 I/O 是否瓶颈
压测结果不准?重点盯住 Threads_created 和 Aborted_clients
容器环境下,Threads_created 暴涨或 Aborted_clients 非零,说明连接管理出问题——不是 SQL 慢,而是连接建立/释放本身成了瓶颈。
常见原因:
- sysbench 默认长连接,但容器里 MySQL 的
wait_timeout过短(默认 28800 秒),而压测脚本未显式设置--mysql-socket或--mysql-ignore-errors - Docker 网络层 NAT 转发延迟高,导致连接握手超时(尤其在高
--threads下) - 容器未配
--ulimit nofile=65536:65536,文件描述符耗尽后新连接被拒绝
验证命令:
mysql -u sbtest -p -h 172.16.10.5 -e "SHOW GLOBAL STATUS LIKE 'Threads_created'; SHOW GLOBAL STATUS LIKE 'Aborted_clients';"
若每秒增长 > 10,就得调大 thread_cache_size(建议设为 --threads 的 1/4,但不超过 64)并检查 ulimit。
容器压测最易被忽略的点:MySQL 容器的时区、字符集、SQL mode 与生产不一致,会导致执行计划偏差。哪怕只差一个 sql_mode=STRICT_TRANS_TABLES,sysbench 插入时就可能因隐式类型转换失败,错误率虚高。务必用 SELECT @@sql_mode, @@time_zone, @@character_set_server; 对齐。











