参数调优建议

对于RDS MySQL实例,您可以通过控制台修改参数。对于某些重要参数而言,不恰当的参数值会导致实例性能问题或应用报错,所以本文介绍一些重要参数的优化建议以减少您在设置参数时的疑虑。

说明

参数的默认值请在RDS管理控制台查看。

back_log

  • 适用版本:8.0、5.7、5.6、5.5

  • 修改完后是否需要重启:是

  • 作用:控制MySQL在处理大量短连接请求时的连接队列长度。如果等待连接数超过back_log值,新连接请求将被拒绝。需要处理大量短连接时,应提高此参数值。

  • 现象:如果参数过小,应用可能出现如下错误:

    SQLSTATE[HY000] [2002] Connection timed out;
  • 修改建议:3000

rpl_semi_sync_master_timeout

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:在使用半同步复制的实例中,事务在主库提交前,需要等待备库收到本事务所有的 binlog;当这个等待超过本参数配置的值之后,会触发超时,将整个实例退化到异步复制。发生超时后,如果备库追上了主库所有的 binlog 日志,实例会自动回到半同步复制模式。

  • 修改建议:此参数的单位为毫秒,建议将此参数设置为 1000(1秒)。对于数据可靠性要求高的实例,可以调高此参数来防止半同步复制退化,但需注意,如果此参数设置过高,在执行大事务时可能出现长时间的实例不可写,导致 HA 探活失败进而引发切换。

innodb_autoinc_lock_mode

  • 适用版本:8.0、5.7、5.6、5.5

  • 修改完后是否需要重启:是

  • 作用:从MySQL 5.1.22起,InnoDB引入了参数innodb_autoinc_lock_mode,用于控制自增主键的锁机制。该参数取值说明如下:

    • 0(传统模式):SQL语句取自增值前会持有自增锁,直至语句执行结束释放自增锁,这种模式会严重影响插入的并发度。

    • 1(默认值,连续模式):SQL语句取自增值前会持有自增锁,对于插入行数确定的SQL语句,取完自增值后立刻释放自增锁;对于插入行数不确定的SQL语句,在语句结束时释放自增锁。

    • 2 (交叉模式):SQL语句取自增值前会持有自增锁,但无论插入行数是否确定,取完自增值后立即释放锁。

  • 修改建议:建议将该参数值改为2,这样可以避免auto_inc的死锁,并提升INSERT … SELECT的性能。

    说明

    当参数值为2时,binlog的格式需设置为row。

query_cache_size

  • 适用版本:5.7、5.6、5.5

  • 修改完后是否需要重启:否

  • 作用:该参数用于控制MySQL query cache的内存大小。如果开启query cache,查询时会先检查缓存,命中则返回缓存结果,未命中则正常执行查询并将结果存入缓存。任何对表的写操作(如INSERT、UPDATE、DELETE等)或结构变化都会使与该表相关的query cache失效,增加系统负担。因此,query cache适用于更新不频繁的数据库,但在频繁写入的情况下可能导致锁冲突,降低查询效率。

  • 现象:数据库中有大量的连接状态为checking query cache for queryWaiting for query cache lockstoring result in query cache

  • 修改建议:RDS默认关闭query cache,如果您的实例打开了query cache,当出现上述情况后可以关闭query cache。

net_write_timeout

  • 适用版本:8.0、5.7、5.6、5.5

  • 修改完后是否需要重启:否

  • 作用:等待将一个block发送给客户端的超时时间。

  • 现象:若参数设置过小,可能会导致客户端出现如下错误:

    the last packet successfully received from the server was milliseconds agothe last packet sent successfully to the server was milliseconds ago.
  • 修改建议:默认值为60秒。建议在网络条件较差或客户端处理每个block耗时较长时,增加该参数的大小,以避免连接中断。

tmp_table_size

  • 适用版本:8.0、5.7、5.6、5.5

  • 修改完后是否需要重启:否

  • 作用:该参数用于设定每个线程分配的内部内存临时表的最大值,实际限制由tmp_table_sizemax_heap_table_size中的较小值决定。超出限制时,MySQL会自动将其转化为基于磁盘的表(在MySQL 8.0中为InnoDB表)。优化查询时应尽量避免使用临时表,若无法避免,应保证临时表在内存中。

  • 现象:复杂SQL语句中包含GROUP BY、DISTINCT等无法通过索引优化的临时表,会导致SQL执行时间加长。

  • 修改建议:默认值为2097152。若应用中有很多GROUP BY、DISTINCT语句且内存充足,可增大tmp_table_size(max_heap_table_size)提升查询性能。

loose_rds_max_tmp_disk_space

  • 适用版本:5.6、5.5

  • 修改完后是否需要重启:否

  • 作用:用于控制MySQL能够使用的临时文件的大小。

  • 现象:如果临时文件超出loose_rds_max_tmp_disk_space的取值,则会导致应用出现如下错误:

    The table ‘/home/mysql/dataxxx/tmp/#sql_2db3_1’ is full
  • 修改建议:首先,分析导致临时文件增加的SQL语句是否可优化。其次,如果实例空间足够,可以提升此参数值,以保证SQL能够正常执行。

loose_tokudb_buffer_pool_ratio

  • 适用版本:5.6

  • 修改完后是否需要重启:是

  • 作用:用于控制TokuDB引擎可使用的buffer内存大小。例如,若将innodb_buffer_pool_size设置为1000 MB,tokudb_buffer_pool_ratio设置为50(即50%),则TokuDB引擎的表可使用的buffer内存大小为500 MB。

  • 修改建议:在RDS使用TokuDB引擎时调大该参数,以提升访问性能。

loose_max_statement_time

  • 适用版本:5.6

  • 修改完后是否需要重启:否

  • 作用:用于控制查询(QUERY)在数据库中的最长执行时间。如果超过该参数设置的时间,查询将会失败,默认是不限制。

  • 现象:若查询时间超过了该参数的值,则会出现如下错误:

    ERROR 3006 (HY000): Query execution was interrupted, max_statement_time exceeded
    说明

    参数修改后仅对新连接生效,保持中的连接需要断开重连才能生效。

  • 修改建议:如果您想要控制数据库中SQL的执行时间,则可以开启该参数,单位是毫秒。

loose_rds_threads_running_high_watermark

  • 适用版本:5.6、5.5

  • 修改完后是否需要重启:否

  • 作用:控制MySQL并发的查询数目。例如,将loose_rds_threads_running_high_watermark的值设置为100,则允许100个并发查询,超过的查询将被拒绝。

  • 修改建议:该参数通常在秒杀或者大并发的场景下使用,对数据库具有较好的保护作用。

innodb_buffer_pool_instances

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:是

  • 作用:将innodb_buffer_pool_size大于1 GB的缓冲池拆分成多个实例,每个实例独立管理,支持并发读写。

  • 修改建议:{LEAST(DBInstanceClassMemory/1073741824, 8)}

table_open_cache_instances

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:是

  • 作用:将打开的表缓存划分为几个大小为table_open_cache / table_open_cache_instances的较小缓存实例,减少会话(Session)间表缓存的争用。

  • 修改建议:16

table_open_cache

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:表缓存的数量。用于将表加载到缓存中,实现快速访问。值过小可能导致高并发时SQL性能问题,值过大可能消耗大量内存,调高此参数时请关注内存水位。

  • 修改建议:{LEAST(DBInstanceClassMemory/1073741824*1024, 16384)}

innodb_adaptive_hash_index

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:是否开启自适应哈希索引。自适应哈希索引可以根据您提供的查询条件加速定位到叶子节点,减少IO次数。

  • 现象:开启此参数是否提升性能取决于业务SQL,但部分操作(如DDL)可能引发哈希索引更新,导致SQL阻塞或性能下降。

  • 修改建议:OFF。调整该参数可参照文档RDS MySQL Adaptive Hash Index (AHI)最佳实践

open_files_limit

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:是

  • 作用:该参数用于控制MySQL实例能够同时打开使用的文件句柄数,同时会影响innodb_open_files参数配置。

  • 修改建议:5.6版本为65535,5.78.0版本为655350。如果实例的规格较大(大于或等于32核),同时用户的活跃会话数、表数量较多,可根据实际情况将 open_files_limit 设置为一个合理且略高于实际需求的值。

loose_innodb_rds_faster_ddl

  • 适用版本:8.0、5.7、5.6(内核小版本均为20200630或以上)

  • 修改完后是否需要重启:否

  • 作用:开启该参数后,能够加速部分DDL操作,降低其对性能的影响。

  • 修改建议:如果担心DDL操作对业务产生影响,建议开启此参数。开启后,将使用RDS自研的Buffer Pool页面管理策略,能够对部分DDL操作(如表结构变更)进行加速,降低对业务的影响。

innodb_thread_concurrency

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:InnoDB内部允许使用的最大线程数。值为0表示无并发限制。用于解决实例上并发过高引发的性能问题。

  • 修改建议:如果未遇到高并发性能问题,设置为0(无限制)。

binlog_transaction_dependency_history_size

  • 适用版本:8.0(内核小版本为20210930以上),5.7(内核小版本为20211231以上)

  • 修改完后是否需要重启:否

  • 作用:控制内存中保存的事务信息Hash条目的上限,达到限制后会清空所有信息,不会直接影响正在进行的事务。

  • 现象:设置过小会影响备库并行回放的并发度,导致复制延迟。

  • 修改建议:500000。调整该参数可参照文档调整实例WRITESET相关参数

binlog_transaction_dependency_tracking

  • 适用版本:8.0(内核小版本为20210930以上),5.7(内核小版本为20211231以上)

  • 修改完后是否需要重启:否

  • 作用:MySQL的控制并行复制的方法,设置为WRITESET可以检测事务间行级别的冲突,从而在备库实现更快的并行回放。

  • 修改建议:WRITESET。调整该参数可参照文档调整实例WRITESET相关参数

innodb_max_dirty_pages_pct_lwm

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:脏页高于该百分比时启动刷脏操作。设置此参数为0意味着禁止预刷脏,应该始终低于innodb_max_dirty_pages_pct的值。

  • 修改建议:10

eq_range_index_dive_limit

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:当查询中的等值范围数大于等于该值时,优化器使用统计信息计算执行计划;否则,使用index dive方式采样统计信息。

    • 例:

      col_name IN(val1, ..., valN)
      col_name = val1 OR ... OR col_name = valN

      即包含N个等值范围。

    • 更多信息请参见官网文档

  • 修改建议:5.6版本为10,5.78.0版本为100。

innodb_flush_neighbors

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:指定从InnoDB缓冲池中刷新一个脏页时,是否也会刷新和该脏页同簇的其他脏页。

    • 设置为0表示同簇的其他脏页不会被刷新。

    • 设置为1表示会刷新同簇内和该脏页相邻的其他脏页。

    • 设置为2表示会刷新同簇内的所有脏页。

  • 修改建议:0

innodb_lock_wait_timeout

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:InnoDB事务在放弃获取行锁之前需要等待的时间,单位为秒。

  • 修改建议:50

innodb_lru_scan_depth

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:指定页面清理线程在扫描缓冲池的LRU页面链表时的扫描深度,该参数会影响缓冲池的刷脏操作。

  • 修改建议:{LEAST(DBInstanceClassMemory/1048576/8, 8192)}

innodb_purge_threads

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:是

  • 作用:用于InnoDB清理undo记录的后台线程数。增加该值将创建额外的清理线程,可以提升undo清理的效率,防止undo日志占用过多空间,从而间接影响在多个表上执行DML操作的系统性能。

  • 修改建议:LEAST(DBInstanceClassMemory/1073741824, 8)

innodb_log_file_size

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:是

  • 作用:

    • REDO日志组中每个日志文件的大小。日志文件大小之和(innodb_log_file_size * innodb_log_files_in_group)不能超过512 GB。默认值为48 MB。

    • 日志文件应足够大,以处理超过一小时的写活动,平滑工作负载高峰和低谷。较大的日志文件减少缓冲池中的检查点刷新活动,节省磁盘I/O,但会使崩溃恢复变慢。

  • 修改建议:随规格变化。

innodb_sync_array_size

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:是

  • 作用:定义互斥锁/锁等待数组的大小。增加该值可以提高具有大量等待线程的工作负载的并发性。该值必须在MySQL实例启动时配置,之后不能更改。对于经常产生大量等待线程(通常大于768)的工作负载,建议增加该值。

  • 修改建议:128

innodb_page_cleaners

  • 适用版本:8.0、5.7

  • 修改完后是否需要重启:是

  • 作用:定义页面清理线程数量,默认值为4,超过缓冲池实例数量时自动调整为与缓冲池实例数量相同。

  • 修改建议:8

innodb_open_files

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:是

  • 作用:该参数指定InnoDB能够同时打开的最大文件句柄数。

  • 现象:如该值设置较小,可能会出现如下错误,影响实例性能:

    [Warning] [MY-012152] [InnoDB] Open files * exceeds the limit *
  • 修改建议:20000

default_time_zone

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:是

  • 作用:默认时区。

  • 现象:未设置时使用主机时区,可能导致应用程序或数据库在处理时间相关的操作时出现不一致的行为,例如,跨多个时区的应用程序可能会遇到时间转换错误或不一致的时间戳记录。此外,频繁的时间转换和时区调整操作可能增加系统的计算负担,进而导致CPU使用率上升。

  • 修改建议:根据实际使用需求设置为相应的时区。调整该参数可参照文档RDS MySQL参数time_zone最佳实践

general_log

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:指定是否开启general log。

  • 现象:开启general log会产生一些问题,详情请参见RDS MySQL General log常见问题

  • 修改建议:OFF

innodb_io_capacity

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:指定InnoDB后台任务每秒可用的I/O操作数。

  • 修改建议:20000

innodb_io_capacity_max

  • 适用版本:8.0、5.7、5.6

  • 修改完后是否需要重启:否

  • 作用:定义InnoDB后台任务在刷新活动落后时的最大IOPS。

  • 修改建议:40000