几年前,Stephane Combaudon 写了一篇博文 《安装 MySQL 后,需要调整的 10 个性能配置项》(Ten MySQL performance tuning settings after installation) 内容覆盖了 MySQL 5.1, MySQL 5.5 和 MySQL 5.6 这几个老版本的 MySQL。在本文中,我将研究如何对 MySQL 5.7 进行调优(关注 InnoDB 存储引擎)。
一个好消息是,MySQL 5.7 提供了更加合适的默认值。Morgan Tocker 制作了关于一份 MySQL 5.7 的特性完整列表,这是一个很好的参考资料。例如,下面的几个变量都是默认设置的:
- innodb_file_per_table = ON
- innodb_stats_on_metadata = OFF
- innodb_buffer_pool_instances = 8 (or 1 if innodb_buffer_pool_size < 1GB)
- query_cache_type = 0; query_cache_size = 0; (disabling mutex)
在 MySQL 5.7 中,实际上只有 4 个重要的选项需要去调整。然而,还有其他的 InnoDB 或者全局的 MySQL 选项可能需要根据特定的负载和硬件来做出调整。
首先,在 my.cnf 中的[mysqld] 节下面添加如下配置。配置完成之后,需要重启 MySQL 服务:
[mysqld]
# other variables here
innodb_buffer_pool_size = 1G # (adjust value here, 50%-70% of total RAM)
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 1 # may change to 2 or 0
innodb_flush_method = O_DIRECT
说明:
选项 | 值 |
---|---|
innodb_buffer_pool_size | 设置为 RAM 大小的 50%-70%,不需要大于数据库的大小 |
innodb_flush_log_at_trx_commit | 1(默认值),0/2 (性能更好,但稳定性更差) |
innodb_log_file_size | 128M – 2G (不需要大于 buffer pool) |
innodb_flush_method | O_DIRECT (避免双缓冲技术) |
下一步
对于新安装的实例而言,那些设置都是很好的起点。还有许多其他的选项,在某些场景下,可以提高 MySQL 的性能。通常,我会部署一套 MySQL 监控/图形工具(例如,Percona 监控语句管理平台,俗称:PMMM),然后根据 MySQL 监控面板提供的信息来执行进一步的调优。
根据监控图表,我们能进一步做什么样的优化?
InnoDB 缓冲池大小的信息,看下面这个图:
从上面可以看出,可用的 RAM 和空闲的页的数量小于缓冲池的总大小,我们可以把 InnoDB 缓冲池的大小增加到 10G 从而获得更好的性能。
InnoDB redo 日志的大小的信息,看下面这个图:
可以看到,InnoDB 通常每小时写 2.26GB 的数据,这已经超出了 redo 日志的大小(2G)。现在我们可以增大 innodb_log_file_size
选项,然后重启 MySQL。另外,使用 "show engine innodb status" 命令来计算一个合适的 InnoDB redo 日志的大小值。
其他选项
有很多其他的 InnoDB 选项可以进一步调整:
- innodb_autoinc_lock_mode
设置 innodb_autoinc_lock_mode = 2 (interleaved mode) 可以去掉表级 AUTO-INC 锁的必要性(还可以提高在使用多行插入语句来插入数据到拥有自增主键的表的时候的性能)。这要求 binlog_format=ROW
或者 MIXED
(在 MySQL 5.7 中,默认值是 ROW)。
- innodb_io_capacity 和 innodb_io_capacity_max
这是一个更加高级的调优,只有当你在频繁写操作的时候才有意义(它不适用于读操作,例如 SELECTs)。若你真的需要对它进行调整,最好的方法是要了解系统可以支持多大的 IOPS。譬如,假设服务器有一块 SSD 硬盘,我们可以设置 innodb_io_capacity_max=6000
和 innodb_io_capacity=3000
(最大值的一半)。运行 sysbench 或者任何其他基准工具来对磁盘吞吐量来进行基准测试是一个好方法。
然而,我们需要去担心这个选项吗?看下面这张缓冲池的"脏页"
在这种情况下,脏页的总量很大,而且看起来 InnoDB 刷新脏页的速度跟不上脏页的速度。如果我们有一个高速的磁盘子系统(例如:SSD),可以增加 innodb_io_capacity
和 innodb_io_capacity_max 来得到更好的性能。
总结(太长,请不要看版本)
新的 MySQL 5.7 配置项的默认值对于一般的负载更加友好。与此同时,我们仍然需要配置 InnoDB 的选项来发挥出大内存的优势。
安装完毕之后,遵循以下步骤来操作:
- 如上所述,在 my.cnf 中配置 InnoDB 选项,并重启 MySQL 服务
- 部署一套监控系统(例如:Percona 监控语句管理平台)
- 通过监控图形来判断是否对 MySQL 进一步调优