作者:Wayne Leutwyler,Percona 技术客户经理
原文:percona.community/blog/2026/0... 1, 2026
爱可生开源社区翻译,本文约 1900 字,预计阅读需要 8 分钟。

有一种只有 DBA 才能体会的无聊。就是盯着运行的服务器,心想:肯定有什么地方可以优化。好消息是:确实有。
本文将详细 介绍几个能提升 MySQL 性能的变量,解释它们的重要性,以及调整这些变量何时能带来性能提升,何时又会悄然降低性能。本文主要针对 InnoDB 存储引擎。
1. innodb_buffer_pool_size
1.1 真正值得关注的指标
在修改这个变量之前,请先查看以下内容:
sql
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';
关键字段:
Innodb_buffer_pool_reads- 从磁盘的物理读取Innodb_buffer_pool_read_requests-- 逻辑读取
**经验法则:**如果 reads/read_requests > 1-2%,则说明您的缓冲池太小。
1.2 示例图表
绘制 Innodb_buffer_pool_reads 随时间变化的曲线。健康的系统曲线应保持平稳或缓慢上升。出现类似城市天际线的峰值通常意味着内存压力过大或缓存冷却。
如果说 MySQL 性能方面有一颗璀璨的明珠,那非它莫属。
1.3 它的作用
InnoDB 缓冲池会将表数据和索引缓存到内存中。从内存读取数据速度很快。从磁盘读取数据......简直是磨练意志。
1.4 如何调整它
- 专用数据库服务器:占用系统内存的 60%--75%
- 共享服务器:要节约内存,为操作系统和其他服务预留内存
sql
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
1.5 特别提示
如果你的数据库集群能够增加缓冲池,MySQL 会给你带来神奇的体验。但如果放不下,再多的查询优化也无济于事。
2. innodb_buffer_pool_instances
当内存容量增大时,这一点就显得尤为重要。
2.1 它的作用
将缓冲区池拆分为多个实例,以减少内部互斥锁争用。
2.2 如何调整它
- 仅当 缓冲池大小 ≥ 1GB 时才相关
- 经验法则:每 1-2GB 内存 1 个实例,最多 8 个实例
sql
SHOW VARIABLES LIKE 'innodb_buffer_pool_instances';
2.3 特别提示
并非越多越好。实例过多会浪费内存,并可能降低性能。
3. innodb_log_file_size
3.1 真正值得关注的指标
sql
SHOW GLOBAL STATUS LIKE 'Innodb_log%';
请注意:
- Innodb_log_waits
- Innodb_log_write_requests
如果 Innodb_log_waits 不为零,则 Redo Log 日志对于您的写入速率来说太小。
3.2 示例图表
绘制 Innodb_log_waits 每秒速率图。理想情况下,这条线应该紧贴零点,就像它害怕高度一样。
该变量控制 MySQL 处理写入密集型工作负载的平稳程度。
3.3 它的作用
定义重做日志的大小。日志越大,检查点就越少,写入过程也越流畅。
3.4 如何调校它
- OLTP 业务 通常 Redo Log 总量为 1-4GB。
- 大型交易受益于更大的日志
sql
SHOW VARIABLES LIKE 'innodb_log_file_size';
3.5 特别提示
改变这一点需要重新开始。请做好相应计划,否则将承受未来值班时的自己带来的怒火。
4. innodb_flush_log_at_trx_commit
4.1 真正值得关注的指标
sql
SHOW GLOBAL STATUS LIKE 'Innodb_os_log_fsyncs';
从 1 切换到 2 通常 可以大幅减少 fsync 次数。
4.2 示例图表
两条线重叠:
- Transactions per second
- Innodb_os_log_fsyncs per second
对于繁忙的系统而言,仅凭这张图表就足以让持怀疑态度的审计人员相信进行更改的合理性。
性能与耐用性,永恒的较量。
4.3 它的作用
控制 Redo Log 日志刷新到磁盘的频率。
4.4 属性值
1 -- 最安全,最慢(每次提交都刷新) 2 -- 非常受欢迎的折衷方案 0 -- 快速、高风险
sql
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
4.5 现实检验
对于许多生产系统而言,配置属性 2 可以在可接受的风险范围内带来巨大的性能提升,尤其是在可靠的存储条件下。
5. innodb_flush_method
这个变量决定了 MySQL 如何与磁盘通信。
5.1 它的作用
控制 MySQL 是否使用操作系统缓存或绕过操作系统缓存。
5.2 推荐的配置
sql
innodb_flush_method=O_DIRECT
这样可以避免 MySQL 和操作系统页面缓存之间的双重缓冲。
5.3 特别提示
某些叫旧的文件系统和内核表现可能有所不同,务必进行测试。
6. max_connections
这不是性能调节的旋钮,而是控制耗损的旋钮。
6.1 它的作用
限制并发客户端连接数。
6.2 为什么这很重要
每个连接都会消耗内存,连接过多会导致 MySQL 崩溃。
sql
SHOW VARIABLES LIKE 'max_connections';
6.3 特别提示
- 设定得切合实际一些
- 使用连接池
- 监控
Threads_connected
7. thread_cache_size
7.1 真正值得关注的指标
sql
SHOW GLOBAL STATUS LIKE 'Threads%';
关键字段:
- Threads_created
- Connections
如果 Threads_created / Connections 始终高于几个百分点,则说明您的缓存容量不足。
7.2 示例图表
将线程数 Threads_created 作为计数器。一个健康的系统会呈现随时间推移而趋于平缓的曲线,而不是阶梯状曲线。
小改变,大胜利。
7.3 它的作用
缓存线程,这样 MySQL 就不会不断地创建和销毁线程。
7.4 如何调整它
sql
SHOW STATUS LIKE 'Threads_created';
如果该数值持续上升,则增加 thread_cache_size。
8. table_open_cache 和 table_definition_cache
元数据比人们想象的更重要。
8.1 它们的作用
缓存打开的表和表结构,以避免重复访问文件系统。
Opened_tables值高- 元数据锁定等待
sql
SHOW VARIABLES LIKE 'table_open_cache';
SHOW VARIABLES LIKE 'table_definition_cache';
9. tmp_table_size 和 max_heap_table_size
9.1 真正值得关注的指标
sql
SHOW GLOBAL STATUS LIKE 'Created_tmp%';
观察:
- Created_tmp_tables
- Created_tmp_disk_tables
如果磁盘临时表超过总临时表的 5% 至 10%,则查询会溢出到磁盘。
9.2 示例图表
堆积面积图:
- 内存临时表
- 基于磁盘的临时表
磁盘使用率缓慢上升通常表明存在伪装成 OLTP 的报表查询。
基于磁盘的临时表是性能的隐形杀手。
9.3 它们的作用
限制内存临时表的大小。
9.4 如何调整他们
将两者设置为相同的值:
ini
tmp_table_size=256M
max_heap_table_size=256M
9.5 特别提示
这有助于解决复杂的查询问题,但仍然需要修复错误的查询。
10. slow_query_log 和 long_query_time
这不是一项绩效指标,而是一项绩效启示 。
10.1 为什么这很重要
你无法调整你看不见的东西。
sql
slow_query_log=ON
long_query_time=1
这使得猜测变成了证据。
关于绘制这些指标图表的说明
你不需要什么特殊的工具。这些工具就很好用:
performance_schemasysschema 视图- Prometheus + mysqld_exporter
- Percona Monitoring and Management (PMM)
黄金法则:永远绘制比率图表,而不是原始计数。
最后想说的话
MySQL 的优化与其说是调整无穷无尽的参数,不如说是 了解压力点:
- 第一是内存
- 第二是 I/O
- 第三是并发性
大多数性能提升都来自于 少数几个变量,而不是充满传奇色彩的复杂配置文件。
如果今天只能调整一项,那就调整缓冲池。如果只能调整两项,那就添加 Redo Log。其他一切都是精益求精。
如果你明天又觉得无聊,恭喜你,你正式成为一名数据库专家了。∎