简介:MySQL高峰期莫名变慢,CPU不高、内存够用,问题出在哪?90%的性能瓶颈都藏在默认配置里。本文按重要程度梳理20个必调核心参数,覆盖内存、I/O、连接、日志、复制五大模块,并提供电商、内容、开发三套即用场景模板,帮你快速定位瓶颈、少走弯路
搞 MySQL 这么多年,见过太多"硬件没问题,配置一塌糊涂"的案例。朋友上周找我求助:高峰期卡得不行,CPU 不高、内存也够,就是慢。登上服务器一看 my.cnf——除了 datadir,全是默认值。
说实话,这不是个例。90% 的 MySQL 性能问题,都出在默认配置上。
今天把从业以来最常调的 20 个参数按重要程度排好序,覆盖五大模块,文末附三套场景模板,可以直接抄作业。
MySQL 最重要的参数,没有之一。
Buffer Pool 是 InnoDB 缓存数据页和索引页的内存区域,命中率直接决定读写性能。
| 部署方式 | 建议占比 | 示例(64G 内存) |
|---|---|---|
| 专用数据库服务器 | 60%-80% | 48G-50G |
| 混合部署服务器 | 40%-50% | 24G-30G |
查看命中率:
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';
-- 命中率 = 1 - Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
-- 低于 99% 就该加大
MySQL 5.7+ 推荐设为 8 或 16,减少 Buffer Pool 内部锁竞争。
注意:buffer_pool_size 大于 1G 时这个参数才有意义。
日志缓冲区,默认 16M。有大量大事务(比如批量 INSERT)时,可以调到 64M。
控制内存临时表大小,默认只有 16M。复杂查询一超限就落盘,性能断崖式下跌。建议统一设为 64M-256M。
事务安全性的核心参数,三个取值:
| 值 | 行为 | 使用场景 |
|---|---|---|
| 1(默认值) | 每次提交都刷盘,最安全最慢 | 金融/交易系统 |
| 0 | 每秒刷盘,可能丢 1 秒数据 | 日志类业务 |
| 2 | 写到 OS 缓存,每秒刷盘 | 一般业务,性能提升明显 |
控制 binlog 刷盘策略:
非核心业务可以考虑 flush_log=2, sync_binlog=1,性能提升很明显。
告诉 InnoDB 你的磁盘 IOPS 能力:
| 磁盘类型 | 建议值 |
|---|---|
| SSD | 2000~20000 |
| NVMe SSD | 10000~50000 |
| HDD | 200(默认值,别改太大) |
设太小,脏页刷新不及时;设太大,刷盘太猛影响前台请求。
| 值 | 说明 |
|---|---|
| O_DIRECT(推荐) | 绕过 OS 缓存,避免双重缓存 |
| fsync(默认) | 走 OS 缓存 |
数据库服务器建议统一设为 O_DIRECT。
默认 151,很多"Too many connections"报错就是它太小
配合连接池使用,不需要设太大。一定要同步调大 open_files_limit
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
接近 max_connections 就需要调大
避免频繁创建销毁线程,建议设为 64~256
SHOW GLOBAL STATUS LIKE 'Threads_created';
这个值增长太快,说明 thread_cache_size 不够
默认 28800 秒(8 小时),太长了,连接一直占着不释放。
Redo Log 文件大小。5.7 修改需停机,8.0+ 支持在线调整
| 业务类型 | 建议值 |
|---|---|
| 写入密集型 | 2G-4G |
| 读多写少 | 512M-1G |
Redo Log 文件个数,默认 2。总大小 = log_file_size × files_in_group,建议能容纳 1-2 小时的写入量
记录所有 SQL,生产环境不要开,只在排查问题时临时启用
每台 MySQL 必须唯一,主从复制的基石
| 格式 | 说明 |
|---|---|
| ROW(推荐) | 记录行变更,数据最安全 |
| STATEMENT | 记录 SQL 语句,某些函数不安全 |
| MIXED | 混合模式 |
MySQL 8.0+ 已默认 ROW,其他格式已废弃
GTID 复制模式,强烈推荐开启,大幅简化主从切换和故障恢复
1. max_allowed_packet
单个数据包最大大小,默认 64M。有 BLOB/TEXT 大字段的业务建议调到 256M。
2. sql_mode
MySQL 8.0 默认 sql_mode 比 5.7 严格很多,升级前一定要检查:
SELECT @@sql_mode;
重点关注 ONLY_FULL_GROUP_BY 的影响