MySQL 8 IO密集型场景下的参数调优

417 阅读9分钟

本文主要针对MySQL IO密集型场景,列出一些与读写性能相关的数据库参数并对这些参数进行解读,帮助你在MySQL调优的过程中进行参照,希望能帮助你比较明显的提升MySQL的性能,并未您后续的其他MySQL调优场景打开一些思路。

默认情况下,云服务商都会为自己的托管数据库产品提供通用场景优化后的参数配置表,比如AWS RDS MySQL就优默认的参数组,你可以借鉴。但是对于具体的特殊的场景,比如I/O密集型或者计算密集型场景,就需要自己按照自己的场景需求进行部分参数的调整。

典型的可调整参数

名称功能说明调整思路
innodb_buffer_pool_sizeinnodb 缓存表和索引的数据,默认128MB,可以将读取过的index和数据当在内存缓存中避免再次读写磁盘,这将显著减少磁盘的IO压力一般按照服务器的内存比例进行设置,典型的内存比例区间为服务器内存的70%~85%之间,一般不推荐大于等于90%,因为要留给Linux和MySQL其他缓存一部分内存空间(如果对于很小内存的机器,建议直接做固定分配,划分好内存大小)
innodb_adaptive_flushing动态调整刷新脏页的速度,避免突发的大量磁盘IO触发磁盘IO瓶颈,默认为true建议为true
innodb_buffer_pool_instancesinnodb_buffer_pool_size划分为多少个独立的区块,将缓冲池划分为单独的实例可以减少不同线程读取和写入缓存页面时的争用,从而提高并发性能,默认为8(innodb_buffer_pool_size小于1G时为1)可以将innodb_buffer_pool_size按照GB为单位进行分区,一般可以按照你服务器的CPU核心数和期望的并发数进行调整,比如设置为16等
innodb_buffer_pool_chunk_sizeinnodb_buffer_pool中单位chunk的大小,默认为128MB建议检查 innodb_buffer_pool_size = innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances * N,也就是请将innodb_buffer_pool_size参数的值设置为innodb_buffer_pool_instances参数值和innodb_buffer_pool_chunk_size参数值的积的倍数。一般128MB足够了
innodb_redo_log_capacity事务日志,用来在mysql 崩溃后的恢复,设置合理的大小对于mysql的性能非常重要。logfile大小对于性能的影响主要体现在checkpoint上,对于 checkpoint的原理可以参考相关的关系数据库理论,更大的logfile大小可以减少checkpoint的次数,减少disk I/O,但是也会增加崩溃后恢复时间,默认100MB一般按照自己的故障容忍时间和服务器的磁盘、cpu性能来定。建议好的SSD盘可以适当设置大一些,比如512MB或者1GB
innodb_ddl_threads控制用于创建二级索引时的并行线程数量,默认为4一般而言够用了,如果机器核心数多也可以适当改大一点
innodb_ddl_buffer_sizeinnodb_ddl_buffer_size 用于指定进行并行 DDL 操作时能够使用的 buffer 大小,buffer是在所有的 DDL 并行线程中平均分配的,默认为1MB左右。所以一般如果调大 innodb_ddl_threads 变量时,也需要调大 innodb_ddl_buffer_size 的大小一般而言够用了,如果机器核心数多也可以适当改大一点
innodb_log_buffer_sizeinnodb_log_buffer_size 是 redo log 的写缓存,如果 buffer 不够大,就会发生多次 IO write,将缓存中的数据刷到磁盘,默认值为 16MB。大型日志缓冲区使大型事务能够运行,而无需在事务提交之前将日志写入磁盘。因此,如果您有更新、插入或删除许多行的事务,则增大日志缓冲区可以节省磁盘 I/O。对于大批量插入或者更新操作,适当设置这个值会消耗更少的IOPS的同时提升吞吐量
innodb_io_capacityinnodb_io_capacity决定了innodb后台任务刷新数据到磁盘时(譬如从buffer pool刷新页面或从change pool合并页面)每秒可用的IO操作次数(IOPS),默认为200这个部分对很多自建的MySQL非常重要,你需要按照自己的磁盘的IOPS性能进行设置,如果不设置看无法充分发挥磁盘的性能,导致IO性能低下。比如对很多SSD而言,200 IOPS已经远低于它们当前数千甚至上万IOPS的实践能力了。对于专用于数据库的机器建议根据自己的磁盘的实际情况设置为60%~80%左右。
innodb_io_capacity_max这个部分对很多自建的MySQL非常重要,当刷新滞后时,后台任务可以执行的最大IOPS,这个值大于innodb_io_capacity,你可以理解为你磁盘的突发的IOPS能力(有些云服务商的快存储具备此类English)建议根据自己的磁盘的实际情况设置为90%左右,不要超过磁盘实际的最大的IOPS。如果您设置了innodb_io_capacity但没有设置innodb_io_capacity_max,则innodb_io_capacity_max默认是innodb_io_capacity的两倍
innodb_write_io_threadsInnoDB 中写入操作的 I/O 线程数,每个线程最多可以处理 256 个pending的 I/O请求一般按照自己MySQL的使用场景来进行判断,比如读多写少的场景了可以适当调大这个值。对IO密集的场景我个人一般喜欢设置为CPU核心的2倍,但是具体的值你可以自己判断
innodb_read_io_threadsInnoDB 中用于读取操作的 I/O 线程数,每个线程最多可以处理 256 个pending的 I/O请求一般按照自己MySQL的使用场景来进行判断,比如读少写多的场景了可以适当调大这个值。对IO密集的场景我我个人一般喜欢设置为CPU核心的2倍,但是具体的值你可以自己判断
innodb_flush_log_at_trx_commitinnodb_flush_log_at_trx_commit定义数据库写log buffer到磁盘的频率以及方式 ,磁盘写入会影响性能,故而此参数让您可以在性能和持久性之间做出选择。MYSQL RDS默认设置为最安全的1对于非常关键的数据,一般建议设置为1,保证每次事物提交后都会落盘。
sync_binlogsync_binlog 控制 MySQL server 将 binary log 同步到磁盘的频率,MYSQL RDS默认设置为最安全的1,但是同样会对性能有消极影响,除非您可以接受丢失数据,否则不建议修改。对于非常关键的数据,一般建议设置为1,保证每次事物提交后都会落盘。
innodb_adaptive_hash_index是否开启自适应hash索引,默认为true;根据工作负载,可能需要动态启用或禁用自适应哈希索引以提高查询性能,具体取决于您的工作负载。由于自适应哈希索引可能不适用于所有工作负载,因此请使用实际工作负载在启用和禁用它的情况下执行基准测试一般建议打开,这样对于大表中热点数据的点查有明显的优化,但是对范围查询没什么正面的优化。
innodb_commit_concurrency可以同时提交的线程数。值 0(默认值)允许同时提交任意数量的事务。保持默认就好
tmp_table_size & max_heap_table_sizeMYSQL在很多场景譬如UNION操作,子查询,排序分组操作中都可能会生成temporary table,temporary table的最大大小由tmp_table_size 与max_heap_table_size其中较小的值决定,默认为16M,temporary table在大小未超过上限时创建在内存中,一旦超过该上限,temporary table就会自动转为磁盘上的表,这将增加磁盘IO和消耗的时间对于大表的union,join等操作,一般可以适当设置大一点,变成16M的整数倍。
thread_cache_size每建立一个连接,都需要一个线程来与之匹配,此参数用来缓存空闲的线程,以至不被销毁,如果线程缓存中有空闲线程,这时候如果建立新连接,MYSQL就会很快的响应连接请求。这个参数对PHP等没有连接池的语言有效果,我习惯设置为32
sort_buffer_size用于指定排序操作中使用的缓存大小。具体来说,当 MySQL 执行需要排序的查询语句时,sort_buffer_size 参数指定了 MySQL 用于排序操作的内存缓存大小,底层原理是,MySQL 在执行排序操作时,需要将需要排序的数据先加载到内存中,然后进行排序操作。如果数据量较大,MySQL 可能需要多次进行排序操作。sort_buffer_size 参数指定了 MySQL 每次排序操作所使用的缓存大小,以便提高排序操作的效率。ySQL中的sort_buffer_size参数大小的设置问题,一般我习惯对大表设置为1M或者2M
join_buffer_sizejoin_buffer_size是MySQL中处理join操作的缓冲区大小,其主要用于储存需要join的表中的数据。当MySQL需要join两个表时,它会将第一个表的所有数据读入缓冲区中,并通过缓冲区中的数据来获取第二个表的相关数据。在连接操作中,join_buffer_size的大小对查询性能有直接的影响。默认256K对于大表间的join可以适当设置大一点,并结合sort_buffer_size来综合考虑
max_allowed_packet默认64MB对于批量insert或者update可以适当调高
net_buffer_length默认16MB
bin_log对大量的insert或者update操作,建议临时关闭

对于MySQL IO密集型场景下的参数调优,硬件层面的考虑也必不可少,对于生产环境在价格可接受的情况下,尽量买高IOPS的SSD盘避免磁盘IO瓶颈、合理使用内存进行数据的缓存和合并减少磁盘IO压力、充分利用多核CPU的并发读写能力是三个主要的调优思路。至于索引优化是业务设计上的例外的一个技术话题。

参考