對于RDS MySQL實例,您可以通過控制臺修改參數。對于某些重要參數而言,不恰當的參數值會導致實例性能問題或應用報錯,所以本文介紹一些重要參數的優化建議以減少您在設置參數時的疑慮。
參數的默認值請在RDS管理控制臺查看。
back_log
適用版本:8.0、5.7、5.6、5.5
修改完后是否需要重啟:是
作用:MySQL每處理一個連接請求時都會創建一個新線程與之對應。在主線程創建新線程期間,如果前端應用有大量的短連接請求到達數據庫,MySQL會限制這些新的連接進入請求隊列,由參數back_log控制。如果等待的連接數量超過back_log的值,則不會接受新的連接請求,所以如果需要MySQL能夠處理大量的短連接,需要提高此參數的大小。
現象:如果參數過小,應用可能出現如下錯誤:
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、1、2,其含義解釋如下:
0 表示傳統模式,SQL語句取自增值前會持有自增鎖,SQL語句結束時釋放自增鎖,這種模式會嚴重影響插入的并發度。
1 表示連續模式,SQL語句取自增值前會持有自增鎖,對于插入行數固定的SQL語句,取完自增值之后立刻釋放自增鎖;對于插入行數不確定的SQL語句,在語句結束時釋放自增鎖。
2 表示交叉模式,SQL語句取自增值前會持有自增鎖,取完自增值后,不論SQL語句的插入行數是否確定,都立即釋放自增鎖。
修改建議:建議將該參數值設置為2,表示所有情況插入都使用輕量的鎖,這樣可以提升插入性能,并且避免auto_inc的死鎖。RDS MySQL的 binlog 使用row模式,配置此參數為2不會引起數據不一致。
說明當該參數值為2時,binlog的格式需要被設置為row。
query_cache_size
適用版本:5.7、5.6、5.5
修改完后是否需要重啟:否
作用:該參數用于控制MySQL query cache的內存大小。如果MySQL開啟query cache,在執行每一個query的時候會先鎖住query cache,然后判斷是否存在于query cache中,如果存在則直接返回結果,如果不存在,則再進行引擎查詢等操作。同時,INSERT、UPDATE和DELETE等操作都會導致query cache失效,這種失效還包括結構或者索引的任何變化。但是cache失效的維護代價較高,會給MySQL帶來較大的壓力。所以,當數據庫不會頻繁更新時,query cache是很有用的,但如果寫入操作非常頻繁并集中在某幾張表上,那么query cache lock的鎖機制就會造成很頻繁的鎖沖突,對于這一張表的寫和讀會互相等待query cache lock解鎖,從而導致SELECT的查詢效率下降。
現象:數據庫中有大量的連接狀態為
checking query cache for query
、Waiting for query cache lock
、storing 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 ago或the last packet sent successfully to the server was milliseconds ago.
修改建議:該參數在RDS中默認設置為60秒,一般在網絡條件比較差時或者客戶端處理每個block耗時較長時,由于net_write_timeout設置過小導致的連接中斷很容易發生,建議增加該參數的大小。
tmp_table_size
適用版本:8.0、5.7、5.6、5.5
修改完后是否需要重啟:否
作用:該參數用于決定內部內存臨時表的最大值,每個線程都要分配,實際起限制作用的是tmp_table_size和max_heap_table_size的最小值。如果內存臨時表超出了限制,MySQL就會自動地把它轉化為基于磁盤的MyISAM表。優化查詢語句的時候,要避免使用臨時表,如果實在避免不了的話,要保證這些臨時表是存在內存中的。
現象:如果復雜的SQL語句中包含了GROUP BY、DISTINCT等不能通過索引進行優化而使用了臨時表,則會導致SQL執行時間加長。
修改建議:如果應用中有很多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設置為1000MB,tokudb_buffer_pool_ratio設置為50(代表50%),那么TokuDB引擎的表能夠使用的buffer內存大小則為500MB。
修改建議:如果RDS中使用TokuDB引擎,建議調大該參數,以此來提升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并發的查詢數目,比如將rds_threads_running_high_watermark的值設置為100,則允許MySQL同時進行的并發查詢為100個,超過限制數量的查詢將會被拒絕掉。
修改建議:該參數通常在秒殺或者大并發的場景下使用,對數據庫具有較好的保護作用。
innodb_buffer_pool_instances
適用版本:8.0、5.7、5.6
修改完后是否需要重啟:是
作用:將innodb_buffer_pool_size大于1 GB的內存緩沖池拆分成多個實例進行維護,每個實例都有自己的鎖、信號量、物理塊(Buffer chunks)以及邏輯鏈表,各實例之間沒有競爭關系,可以并發讀取與寫入。對于緩沖池較大的實例,將緩沖池劃分為單獨的實例可以減少不同線程讀取和寫入時的爭用,進而提高并發性能。
修改建議:
{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*512, 8192)}
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參數配置。
修改建議:建議將此參數設置為655350。如果實例的規格較大(大于或等于32核),同時用戶的活躍會話數、表數量較多,還可根據實際情況再調大open_files_limit參數的值, 該參數配置超過實例文件個數不會對實例的運行造成影響。
loose_innodb_rds_faster_ddl
適用版本:8.0、5.7、5.6(內核小版本均為20200630或以上)
修改完后是否需要重啟:否
作用:該參數開啟后,能夠對部分DDL操作進行加速,降低DDL操作帶來的性能影響。
修改建議:如果用戶擔心DDL操作對業務產生影響,建議開啟此參數。開啟該參數后,將使用RDS內核團隊自研的Buffer Pool頁面管理策略,該頁面管理策略能夠對部分DDL操作進行加速,降低部分DDL執行過程中對業務的影響。
innodb_thread_concurrency
適用版本:8.0、5.7、5.6
修改完后是否需要重啟:否
作用:InnoDB內部允許使用的最大線程數。值為0表示無并發限制。如果實例上并發過高引發性能問題,可以通過修改此參數控制InnoDB中的并發度。
該變量用于在高并發性系統上進行性能調優。
修改建議:如果未遇到高并發性能問題,建議設置為0(無限制)。
binlog_transaction_dependency_history_size
適用版本:8.0(內核小版本為20210930以上),5.7(內核小版本為20211231以上)
修改完后是否需要重啟:否
作用:啟動writeset功能后,會在內存中保存最后修改某一行的事務信息,事務信息是以Hash的方式保存的,該變量控制內存中可以保存的這些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個等值范圍。
該參數更詳細信息見官網文檔https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_eq_range_index_dive_limit。
修改建議:5.6版本為10,5.7和8.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
)不能超過512GB。默認值為48MB。通常,日志文件的大小應該足夠大,以便服務器有足夠的REDO日志空間來處理超過一個小時的寫活動,從而可以平滑工作負載的高峰和低谷。該值越大,緩沖池中需要的檢查點刷新活動就越少,從而節省磁盤I/O。但是較大的日志文件會使崩潰恢復變慢。
修改建議:隨規格變化。
innodb_sync_array_size
適用版本:8.0、5.7、5.6
修改完后是否需要重啟:是
作用:定義互斥鎖/鎖等待數組的大小。增加該值會拆分用于協調線程的內部數據結構,從而在具有大量等待線程的工作負載中獲得更高的并發性。這個值必須在MySQL實例啟動時配置,之后不能更改。對于經常產生大量等待線程(通常大于768)的工作負載,建議增加該值。
修改建議:128
innodb_page_cleaners
適用版本:8.0、5.7
修改完后是否需要重啟:是
作用:從緩沖池實例中清除臟頁的頁面清理線程的數量。當有多個頁清理線程時,每個緩沖池實例的緩沖池刷臟任務將被分派給空閑的頁清理線程。innodb_page_cleaners默認值為4。如果頁面清理線程的數量超過緩沖池實例的數量,innodb_page_cleaners會自動設置為與innodb_buffer_pool_instances相同的值。
修改建議:
{LEAST(DBInstanceClassMemory/1073741824, 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會以高于innodb_io_capacity參數定義的速率來刷新。innodb_io_capacity_max參數即定義了在這種情況下InnoDB后臺任務的最大IOPS。
修改建議:40000