MySQL配置须依硬件定制:内存决定buffer_pool大小,磁盘类型影响flush_method与log参数,CPU核心数调节IO线程数,innodb_flush_log_at_trx_commit需权衡安全与性能,tmpdir和sort_buffer_size应按负载调优,并通过运行时指标验证效果。

MySQL配置要先看内存和磁盘IO能力
MySQL的性能瓶颈通常卡在内存不足或磁盘写入慢上,innodb_buffer_pool_size 和 innodb_log_file_size 这两个参数必须根据实际硬件来调:内存大的机器可以给 buffer pool 分配 70%~80% 的物理内存;但若只有 4GB 内存,硬设成 3GB 反而会触发系统 OOM killer 杀掉 mysqld 进程。
SSD 和 NVMe 的随机写延迟远低于 HDD,所以 innodb_flush_method 在 SSD 上推荐用 O_DIRECT,避免双重缓冲;而老式 SATA HDD 更适合 fsync 配合更大的 innodb_log_buffer_size(比如 8MB~16MB)来摊平写放大。
- 查可用内存:
free -h或cat /proc/meminfo | grep MemTotal - 查磁盘类型:
lsblk -d -o NAME,ROTA(ROTA=1 是机械盘,0 是 SSD/NVMe) - 别直接抄网上的“最佳配置”,
innodb_buffer_pool_instances设太高(如 64)在小内存机器上反而增加锁争用
CPU核心数影响并发线程与日志刷盘节奏
innodb_read_io_threads 和 innodb_write_io_threads 默认都是 4,但在 32 核 CPU + NVMe 的机器上,可提到 8~12;不过超过 CPU 核心数太多没意义——IO 线程本质是异步调度,不是并行计算。
innodb_flush_log_at_trx_commit 是个关键权衡点:设为 1 最安全(每次事务都刷盘),但对高并发写入是性能杀手;设为 2(每秒刷一次 log buffer)在 SSD 上丢数据风险极低,吞吐能翻倍;设为 0 就只靠 OS 缓冲,断电可能丢一秒事务——除非你用的是带电容保护的企业级 SSD,否则别轻易设 0。
- 查逻辑 CPU 数:
nproc或lscpu | grep "^CPU\(s\)" - 如果业务是读多写少(比如报表库),
innodb_thread_concurrency可设为 0(不限制),让 InnoDB 自适应 -
max_connections不是越大越好:每个连接至少占 256KB 内存,设 2000 连接就额外吃掉 500MB,得预留空间
临时表和排序操作依赖 tmpdir 和 sort_buffer_size
大字段 GROUP BY 或 ORDER BY 容易生成隐式临时表,如果 tmpdir 指向的是根分区(/var/lib/mysql 默认在 / 下),磁盘满会导致整个 MySQL 挂起。务必把 tmpdir 改到独立、空间充足、IO 快的挂载点,比如 /data/tmp。
sort_buffer_size 是每个连接独占的内存,设太大(如 32MB)在 500 并发下就吃掉 16GB;设太小(如 32KB)又频繁落盘。建议从 256KB 起步,观察 Sort_merge_passes 状态值:持续 > 100/秒 就说明需要调大。
- 检查当前临时表位置:
SHOW VARIABLES LIKE 'tmpdir'; - 监控排序性能:
SHOW GLOBAL STATUS LIKE 'Sort%'; -
read_buffer_size和read_rnd_buffer_size同理,按需微调,别盲目放大
配置生效后必须验证真实负载表现
改完 my.cnf 重启只是第一步,真正要看的是运行时指标:用 mysqladmin extended -r -i 1 | grep -E "Threads_connected|Innodb_buffer_pool_read_requests|Innodb_buffer_pool_reads" 观察缓存命中率是否 > 99%,Innodb_buffer_pool_reads 持续 > 100/秒 就说明 buffer pool 不够用。
还有容易被忽略的一点:某些云厂商的“突发性能实例”(如 AWS t3/t4g)有 CPU 积分机制,MySQL 启动后短时间内跑满 CPU 可能快速耗尽积分,后续被限频——这种机器只适合低负载或测试环境,别用来跑生产 OLTP。
- 确认配置已加载:
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';" - 检查错误日志是否有警告:
tail -n 50 /var/log/mysql/error.log - 压测时重点盯
wa%(iowait)和%util(iostat -x),而不是只看 QPS


















