在高并发业务场景下,mysql的IO吞吐量常常成为系统瓶颈。磁盘读写速度跟不上请求量,就会出现查询延迟、写入堆积甚至连接数暴涨。要从根本上提升mysql的IO能力,需要从硬件、配置、表结构和SQL写法多个层面入手。

一、调整核心内存与刷盘参数
innodb_buffer_pool_size是决定mysql读IO的关键。它缓存了表和索引数据,设置过小时频繁读盘。一般建议设为物理内存的60%到80%。
-- 查看当前缓冲池大小 SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; -- 在配置文件中设置(单位字节) -- innodb_buffer_pool_size = 4294967296
写IO方面,innodb_flush_method建议设为O_DIRECT,避免操作系统双重缓存。开启innodb_use_native_aio可让linux使用原生异步IO,提升并发吞吐。
二、表空间与文件布局优化
使用独立表空间(innodb_file_per_table=ON)可以让不同表的IO分散,避免共享表空间锁竞争。将 redo log 与数据文件放在不同物理磁盘,也能显著降低写冲突。
| 优化项 | 推荐做法 |
|---|---|
| 表空间 | 开启独立表空间 |
| redo log | 独立高速盘存放 |
| 日志大小 | innodb_log_file_size设大些 |
三、减少写放大与批量提交
频繁小事务会造成大量随机写。把多条insert合并为批量提交,并合理设置sync_binlog与innodb_flush_log_at_trx_commit,在可靠与性能间取舍。
// JDBC批量插入示例
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "u", "p");
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement("INSERT INTO t(a) VALUES(?)");
for (int i = 0; i < 1000; i++) {
ps.setInt(1, i);
ps.addBatch();
}
ps.executeBatch();
conn.commit();
四、表结构及索引设计
过长的索引会增加页大小,加大IO。使用合适的数据类型,避免大字段随意放表里。如果业务允许,可用归档表拆分冷数据,保持热表体积较小,提升缓冲命中率。
IO优化不是单点调参,而是结合业务读写比、磁盘类型和并发模型的综合工程。
通过上述mysql IO吞吐量优化方法,多数线上库能明显降低磁盘负载,提高每秒处理事务数。实际调整前应在测试环境压测,观察iostat与慢查询日志变化。