MySQL一到高峰期就卡?这20个参数不调,再好的硬件也白搭

简介:MySQL高峰期莫名变慢,CPU不高、内存够用,问题出在哪?90%的性能瓶颈都藏在默认配置里。本文按重要程度梳理20个必调核心参数,覆盖内存、I/O、连接、日志、复制五大模块,并提供电商、内容、开发三套即用场景模板,帮你快速定位瓶颈、少走弯路

搞 MySQL 这么多年,见过太多"硬件没问题,配置一塌糊涂"的案例。朋友上周找我求助:高峰期卡得不行,CPU 不高、内存也够,就是慢。登上服务器一看 my.cnf——除了 datadir,全是默认值。

说实话,这不是个例。90% 的 MySQL 性能问题,都出在默认配置上。

今天把从业以来最常调的 20 个参数按重要程度排好序,覆盖五大模块,文末附三套场景模板,可以直接抄作业。

一、内存相关(最优先调)

1. innodb_buffer_pool_size

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% 就该加大

2. innodb_buffer_pool_instances

MySQL 5.7+ 推荐设为 8 或 16,减少 Buffer Pool 内部锁竞争。

注意:buffer_pool_size 大于 1G 时这个参数才有意义。

3. innodb_log_buffer_size

日志缓冲区,默认 16M。有大量大事务(比如批量 INSERT)时,可以调到 64M。

4. tmp_table_size / max_heap_table_size

控制内存临时表大小,默认只有 16M。复杂查询一超限就落盘,性能断崖式下跌。建议统一设为 64M-256M。

二、I/O 相关(决定写入性能)

1. innodb_flush_log_at_trx_commit

事务安全性的核心参数,三个取值:

行为 使用场景
1(默认值) 每次提交都刷盘,最安全最慢 金融/交易系统
0 每秒刷盘,可能丢 1 秒数据 日志类业务
2 写到 OS 缓存,每秒刷盘 一般业务,性能提升明显

2. sync_binlog

控制 binlog 刷盘策略:

  • 1:每次事务提交同步 binlog(配合 flush_log=1 构成"双 1"最高安全配置)
  • 0:由操作系统决定刷盘时机

非核心业务可以考虑 flush_log=2, sync_binlog=1,性能提升很明显。

3. innodb_io_capacity / innodb_io_capacity_max

告诉 InnoDB 你的磁盘 IOPS 能力:

磁盘类型 建议值
SSD 2000~20000
NVMe SSD 10000~50000
HDD 200(默认值,别改太大)

设太小,脏页刷新不及时;设太大,刷盘太猛影响前台请求。

4. innodb_flush_method

说明
O_DIRECT(推荐) 绕过 OS 缓存,避免双重缓存
fsync(默认) 走 OS 缓存

数据库服务器建议统一设为 O_DIRECT。

三、连接与线程(解决连接报错)

1. max_connections

默认 151,很多"Too many connections"报错就是它太小

  • 小型业务建议:300~500
  • 中型业务建议:500~2000

配合连接池使用,不需要设太大。一定要同步调大 open_files_limit

SHOW GLOBAL STATUS LIKE 'Max_used_connections';

接近 max_connections 就需要调大

2. thread_cache_size

避免频繁创建销毁线程,建议设为 64~256

SHOW GLOBAL STATUS LIKE 'Threads_created';

这个值增长太快,说明 thread_cache_size 不够

3. wait_timeout / interactive_timeout

默认 28800 秒(8 小时),太长了,连接一直占着不释放。

  • 非交互连接(wait_timeout):建议300~600 秒
  • 交互连接(interactive_timeout):建议1800 秒

四、日志相关(排查慢查询的基础)

1. innodb_log_file_size

Redo Log 文件大小。5.7 修改需停机,8.0+ 支持在线调整

业务类型 建议值
写入密集型 2G-4G
读多写少 512M-1G

2. innodb_log_files_in_group

Redo Log 文件个数,默认 2。总大小 = log_file_size × files_in_group,建议能容纳 1-2 小时的写入量

3. slow_query_log / long_query_time

  • long_query_time:设为 1 秒(开发环境可设 0.1 秒)
  • log_queries_not_using_indexes:建议开启,记录没走索引的查询

4. general_log

记录所有 SQL,生产环境不要开,只在排查问题时临时启用

五、复制相关(主从架构必调)

1. server_id

每台 MySQL 必须唯一,主从复制的基石

2. binlog_format

格式 说明
ROW(推荐) 记录行变更,数据最安全
STATEMENT 记录 SQL 语句,某些函数不安全
MIXED 混合模式

MySQL 8.0+ 已默认 ROW,其他格式已废弃

3. gtid_mode + enforce_gtid_consistency

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 的影响

调优四条铁律

  1. 一次只改一个参数,观察效果后再改下一个
  2. 先看监控数据,不要凭感觉调参
  3. 大部分参数支持 SET GLOBAL 在线修改,不用重启
  4. 改完必须持久化到 my.cnf,否则重启就丢
编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1