innodb_buffer_pool_size设置过小是磁盘i/o高、查询变慢的主因,导致频繁读盘和刷脏页;命中率低于99%即危险,建议设为物理内存50%–70%,但不超过free -h显示的可用内存。

磁盘I/O高直接拖慢查询,本质是MySQL在等磁盘——不是CPU不够快,而是数据还没从磁盘读上来,或日志还没刷下去。
innodb_buffer_pool_size 设置过小
InnoDB 默认把热数据缓存在 innodb_buffer_pool 里。如果这个池子太小(比如只设了 1G,而实际活跃数据有 20G),就会频繁触发“读盘取页”和“刷脏页回盘”。每次缺页都要等磁盘响应,await 升高、%util 接近 100%,查询自然卡在 Waiting for table flush 或 Writing to net 之前的 I/O 等待阶段。
- 查当前配置:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; - 查命中率:
SHOW STATUS LIKE 'Innodb_buffer_pool_read%';,算(Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests;低于 99% 就危险 - 调大建议:物理内存的 50%–70%,但别超过
free -h显示的可用内存下限
全表扫描 + 缺少索引
没走索引的 SELECT、UPDATE 或 DELETE 会强制扫描整张表。哪怕表只有 100 万行,每行 1KB,也要读 1GB 数据——全靠磁盘扛,iostat -x 1 里 r/s 和 rkB/s 会明显跳升,iotop -oP 直接看到 mysqld 在持续读 /var/lib/mysql/xxx.ibd。
- 定位问题语句:
mysqld --slow-query-log --long-query-time=1开启慢日志,重点看没key字段的EXPLAIN结果 - 加索引前先确认字段选择性,避免对
status这类低基数列建单列索引 -
CREATE INDEX idx_user_id ON orders(user_id);比CREATE INDEX idx_status ON orders(status);更可能缓解 I/O
redo log 刷盘压力大 & binlog 组提交未生效
高并发写入时,如果 innodb_log_file_size 太小(如默认 48MB),会导致 log file 频繁覆盖、checkpoint 被迫提前推进,大量 dirty page 被挤出 buffer pool 并刷盘;同时若 sync_binlog=1 且 innodb_flush_log_at_trx_commit=1,每个事务都得等磁盘落盘,w/s 和 wkB/s 会飙升。
- 检查日志配置:
SHOW VARIABLES LIKE '%log_file_size%';、SHOW VARIABLES LIKE '%flush_log%'; - 生产环境推荐:
innodb_log_file_size = 512M(需停库调整)、innodb_flush_log_at_trx_commit = 2(牺牲极小安全性换 I/O 吞吐) - 注意:
sync_binlog=1000可降低 binlog 写频次,但主从延迟会上升
临时表/排序溢出到磁盘
当 ORDER BY、GROUP BY 或 JOIN 的中间结果集超过 sort_buffer_size 或 tmp_table_size,MySQL 会把临时数据写进 /tmp 或 innodb_temp_data_file_path——这些都在磁盘上。这时候 iostat 里能看到非数据文件路径的写入突增,SHOW PROCESSLIST 中状态常为 Creating sort index 或 Copying to tmp table。
- 查是否溢出:
SHOW GLOBAL STATUS LIKE 'Created_tmp%';,关注Created_tmp_disk_tables增速 - 调参参考:
sort_buffer_size = 4M(每个连接独占,别设过大)、tmp_table_size = 64M(与max_heap_table_size取小值) - 更治本:重写 SQL,用覆盖索引避免排序,或拆分大 GROUP BY
真正卡住人的,往往不是单一原因——buffer pool 小 + 没索引 + 小 redo log,三者叠加会让 I/O 压力呈指数级增长。排查时别只盯一个指标,iostat -x 1、iotop -oP、SHOW ENGINE INNODB STATUS\G 要交叉比对,尤其注意 Innodb_buffer_pool_wait_free 和 Pages flushed 的速率。











