MySQL 社區經理:MySQL 8.4 InnoDB 參數默認值爲什麼要這麼改?

MySQL 8.4 LTS 版本,我們一共修改了 20 個 InnoDB 變量的默認值。

作者:Frederic Descamps,EMEA 和亞太地區的 MySQL 社區經理。於 2016 年 5 月加入 MySQL 社區團隊。擔任開源和 MySQL 顧問已超過 15 年。最喜歡的主題是高可用和高性能。

本文和封面來源:https://lefred.be,愛可生開源社區翻譯。

本文約 2400 字,預計閱讀需要 8 分鐘。

2024 年 4 月 30 日,MySQL 8.4(第一個 LTS 版)正式發佈,也驗證了 Oracle 官方在之前宣佈的 MySQL 版本發佈節奏。

什麼是 LTS 版?目前還有哪些版本?

目前,MySQL 的發佈模型分爲兩個主要路徑:LTS 版(長期支持)和創新版。所有 LTS 和創新版本都包含錯誤和安全修復,並被視爲生產級質量。更多MySQL 版本介紹

MySQL 發佈模型(圖片來源:oracle.com)

什麼情況適合 LTS 版?

  • 需要穩定的功能和更長的支持期。
  • 除了第一個 LTS 版本刪除了一些功能,其他版本僅包含必要的修復,不在刪除功能。
  • LTS 版本遵循 Oracle 終身支持政策(5 年主要支持和 3 年延長支持)。

什麼情況適合創新版?

  • 想了解最新功能、改進。適合快節奏開發環境中的開發和 DBA,具有更高水平的自動化測試和現代持續集成技術,可實現更快的升級週期。
  • 除新功能外,隨着代碼重構、刪除不推薦功能以及修改 MySQL 使其更符合 SQL 標準(在 LTS 版本中不會發生)。
  • 支持至下一個創新版。

MySQL 各版本的生命週期

MySQL 各版本生命週期(圖片來源:oracle.com)

請參考 Oracle 官方提供的 MySQL 各版本生命週期計劃(20240430),以更好地安排您生產環境的 MySQL 版本選擇。

以下內容爲 MySQL 社區經理 Frederic Descamps 對該版本中 InnoDB 參數默認值修改的詳細介紹。

發佈於當地時間 2024 年 5 月 1 日


MySQL 項目經理 Frederic Descamps(圖片來源:oracle.com)

昨天(4/30),MySQL 的第一個 LTS 版本 MySQL 8.4 發佈了。

許多棄用的內容最終被刪除,並且幾個 InnoDB 變量默認值已被修改以匹配當前的工作負載和硬件規格。

有 20 個 InnoDB 變量的默認值已被修改!

讓我們看一下這些變量並解釋這樣修改的原因:

被修改默認值的 InnoDB 變量

innodb_buffer_pool_in_core_file

版本 默認值
8.4 之前 ON
8.4 LTS 如果支持 MADV_DONTDUMP 爲 OFF,否則 ON

MADV_DONTDUMP 是 Linux 3.4 及更高版本中支持的宏(存在“ sys/mman.h”頭文件幷包含符號 MADV_DONTDUMP,一個 madvise() 的 non-POSIX 擴展),Windows 系統或大多數 MacOS 系統不支持此宏。

總之,這意味着默認情況下,在 Linux 系統上,緩衝池的內容不會轉儲到核心文件中。

innodb_buffer_pool_instances

版本 默認值
8.4 之前 8(如果 BP < 1 GB,則爲 1)
8.4 LTS 如果 BP <= 1 GB:1 <br> 如果 BP > 1 GB:則爲 1-64 範圍內的最小值:<br>a. (innodb_buffer_pool_size / innodb_buffer_pool_chunk_size) / 2 <br>b. 1/4 可用邏輯處理器

舊值 8 在某些系統上可能太大。手冊中包含 BP 大小計算的好示例,請參閱 配置 InnoDB 緩衝池大小

innodb_change_buffering

版本 默認值
8.4 之前 all
8.4 LTS none

Change Buffer 是一種通過延遲對二級索引的寫入操作來支持順序 I/O 的技術。在最新的硬件上,隨機 I/O 不再是問題。

innodb_dedicated_server

版本 默認值
8.4 之前 OFF
8.4 LTS OFF

從 MySQL 8.0 開始,當 MySQL 運行在可供數據庫使用的所有資源的專用服務器上時,我們建議啓用此變量,並且不要手動修改 InnoDB 設置。

該變量的默認值是相同的,但是通過啓用 innodb_dedicated_server 控制的變量是不同的。

  • innodb_buffer_pool_size
    • 128MB 是服務器內存小於 1GB。
    • 如果服務器內存在 1GB 到 4GB 之間,則檢測到的服務器內存 * 0.5。
    • 如果服務器內存超過 4GB,則檢測到的服務器內存 * 0.75。
  • innodb_redo_log_capacity:(可用邏輯處理器數量/2)GB,最大 16GB。

innodb_dedicated_server 啓用時,innodb_flush_method 不會自動配置。

innodb_adaptive_hash_index

版本 默認值
8.4 之前 ON
8.4 LTS OFF

AHI(InnoDB 自適應哈希索引)長期以來一直是一些性能問題的原因。每個經驗豐富的 DBA 總是建議禁用它,就像舊的查詢緩存一樣。我很驚訝沒有像 Domas Mituzas 的查詢緩存調優器那樣的 AHI 調優器 😉

當沒有數據發生更改並且完全緩存在緩衝池中時,AHI 可能會對讀查詢 (SELECT) 提供一些好處。一旦有寫入操作,或者系統負載較高,或者讀取所需的所有數據都無法緩存,自適應哈希索引就會成爲巨大的瓶頸。

爲了獲得更可預測的響應時間,建議禁用它。

innodb_doublewrite_files

版本 默認值
8.4 之前 innodb_buffer_pool_instances * 2
8.4 LTS 2

之前默認值是根據緩衝池的數量計算的,爲了簡化,現在默認爲 2。

相關文檔 指出該值定義每個緩衝池的雙寫文件數。但我的印象是,它是全局的,與緩衝池實例的數量無關。

從 MySQL 錯誤日誌來看:

2024-05-01T05:43:03.226604Z 1 [Note] [MY-012955] [InnoDB] Initializing buffer pool, total size = 2.000000G, instances = 2, chunk size =128.000000M 
[...]
2024-05-01T05:43:03.288068Z 1 [Note] [MY-013532] [InnoDB] Using './#ib_16384_0.dblwr' for doublewrite
2024-05-01T05:43:03.295917Z 1 [Note] [MY-013532] [InnoDB] Using './#ib_16384_1.dblwr' for doublewrite
2024-05-01T05:43:03.317319Z 1 [Note] [MY-013532] [InnoDB] Using './#ib_16384_0.bdblwr' for doublewrite
2024-05-01T05:43:03.317398Z 1 [Note] [MY-013566] [InnoDB] Double write buffer files: 2
2024-05-01T05:43:03.317410Z 1 [Note] [MY-013565] [InnoDB] Double write buffer pages per instance: 128
2024-05-01T05:43:03.317423Z 1 [Note] [MY-013532] [InnoDB] Using './#ib_16384_0.dblwr' for doublewrite
2024-05-01T05:43:03.317436Z 1 [Note] [MY-013532] [InnoDB] Using './#ib_16384_1.dblwr' for doublewrite

我們看到我們有 2 個緩衝池實例,但仍然只有 2 個雙寫緩衝文件。根據文檔,我期望 4 。第三個文件 #ib_16384_0.bdblwr 是在 innodb_doublewrite 設置爲 DETECT_ONLY 時創建的。

使用 DETECT_ONLY 時,只有元數據會寫入雙寫緩衝區。數據庫頁內容不會寫入雙寫緩衝區,並且恢復不會使用雙寫緩衝區來修復不完整的頁寫入。此輕量級設置僅用於檢測不完整的頁面寫入。

innodb_doublewrite_pages

版本 默認值
8.4 之前 innodb_write_io_threads(默認爲 4)
8.4 LTS 128

從測試結果和出於對性能的角度考慮,我們意識到默認值越大越好,經常建議增加它。

innodb_flush_method

版本 默認值
8.4 之前 fsync
8.4 LTS O_DIRECT (或 fsync)

當支持時,O_DIRECT 始終是首選值,我們建議使用它繞過文件系統緩存,將 InnoDB 更改刷新到磁盤(對於數據文件和日誌文件)。

如果不支持 O_DIRECT,我們使用舊的 fsync 方法。這是針對 Unix 的,在 Windows 上,默認值是 unbuffered

innodb_io_capacity

版本 默認值
8.4 之前 200
8.4 LTS 10000

對於最近的系統(RAID、SSD 等),默認 I/O 容量太低。由於該變量定義了 InnoDB 後臺操作可用的 IOPS 數量,因此值太低會限制性能。

innodb_io_capacity_max

版本 默認值
8.4 之前 2 * innodb_io_capacity(最小 2000)
8.4 LTS 2 * innodb_io_capacity

如果 InnoDB 需要更積極地刷新,則此變量定義 InnoDB 可用於執行後臺操作的最大 IOPS 數。新的默認值更簡單,因爲它只是 innodb_io_capacity 的兩倍。

innodb_log_buffer_size

版本 默認值
8.4 之前 16MB
8.4 LTS 64MB

我們增加了默認值,因爲大的日誌緩衝區允許大型事務運行,而無需在事務提交之前將日誌寫入磁盤。

innodb_numa_interleave

版本 默認值
8.4 之前 OFF
8.4 LTS ON

當系統支持 NUMA 時,新的默認值在分配 InnoDB 緩衝池期間將 mysqld 的 NUMA 內存策略設置爲 MPOL_INTERLEAVE 。此操作隨機平衡所有 NUMA 節點的內存分配,從而在這些節點之間實現更好的分佈。

當然,只有當您的系統具有多個 NUMA 節點時,您才能從中受益。

這是驗證節點數量的方法:

$ numactl --hardware
	available: 2 nodes (0-1)
	node 0 size: 16160 MB
	node 0 free: 103 MB
	node 1 size: 16130 MB
	node 1 free: 83 MB
	node distances:
	node   0   1 
	  0:  10  20 
	  1:  20  10

在上面的例子中,我們可以看到 CPU 有兩個節點。

您還可以使用 lstopo 顯示架構並顯示 NUMA 核心。這是另一個例子:

innodb_page_cleaners

版本 默認值
8.4 之前 4
8.4 LTS innodb_buffer_pool_instances

新的默認設置是使用與緩衝池實例一樣多的線程從緩衝池實例中刷新髒頁。

innodb_parallel_read_threads

版本 默認值
8.4 之前 4
8.4 LTS 邏輯處理器 / 8(最少 4 個)

出於性能原因,在具有大量邏輯 CPU 的系統上,用於並行聚集索引讀取的線程數會自動增加。

innodb_purge_threads

版本 默認值
8.4 之前 4
8.4 LTS 如果邏輯處理器 <= 16,則爲 1,否則爲 4

對於具有大量 (>=16) vCPU 的系統,此變量也會以某種方式自動配置。但我們也意識到,在某些較小的系統上擁有 4 個清除線程可能會出現問題。對於這樣的系統,我們將默認值減少到 1。

innodb_read_io_threads

版本 默認值
8.4 之前 4
8.4 LTS 邏輯處理器 / 2(最少 4 個)

如果系統有超過 8 個 vCPU,該變量也會自動增加。

innodb_use_fdatasync

版本 默認值
8.4 之前 OFF
8.4 LTS ON

在支持它的系統上,除非需要,否則 fdatasync() 的調用不會刷新對文件元數據的更改。這提供了性能優勢。

temptable_max_ram

版本 默認值
8.4 之前 1GB
8.4 LTS 總內存的 3%(1-4GB 範圍內)

如果系統受益於大量內存,默認值現在會自動增加。但默認上限爲 4GB。因此,對於內存超過 132GB 的系統,默認情況下 temptable_max_ram 的值將設置爲 4GB。

temptable_max_mmap

版本 默認值
8.4 之前 1GB
8.4 LTS 0(禁用)

新的默認設置禁止從內存映射臨時文件分配內存(不在 tmpdir 中創建文件)。

temptable_use_mmap

版本 默認值
8.4 之前 ON
8.4 LTS OFF

temptable_use_mmap 被禁用(新默認設置)時,TempTable 存儲引擎會使用 InnoDB 磁盤上的內部臨時表,而不是在 temptable_max_ram 變量定義的限制被超過時,在 tmpdir 中爲內部內存臨時表分配空間作爲內存映射的臨時文件。

總結

通過這個全新版本的 MySQL(第一個 LTS),我們有機會更改某些 InnoDB 變量的默認值,使它們更符合生產服務器的實際情況。

有些現在可以自動調整以更好地匹配 MySQL 運行的系統。

享受 MySQL 並享受新的默認設置!

參考

[1] MySQL 版本介紹: https://dev.mysql.com/doc/refman/8.4/en/mysql-releases.html

[2] MySQL 8.4: https://dev.mysql.com/doc/relnotes/mysql/8.4/en/

[3] 配置 InnoDB 緩衝池大小: https://dev.mysql.com/doc/refman/8.4/en/innodb-buffer-pool-resize.html

[4] sysvar_innodb_doublewrite_files: https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html#sysvar_innodb_doublewrite_files

本文原文:https://lefred.be/content/mysql-8-4-lts-new-production-ready-defaults-for-innodb/

更多技術文章,請訪問:https://opensource.actionsky.com/

關於 SQLE

SQLE 是一款全方位的 SQL 質量管理平臺,覆蓋開發至生產環境的 SQL 審覈和管理。支持主流的開源、商業、國產數據庫,爲開發和運維提供流程自動化能力,提升上線效率,提高數據質量。

SQLE 獲取

類型 地址
版本庫 https://github.com/actiontech/sqle
文檔 https://actiontech.github.io/sqle-docs/
發佈信息 https://github.com/actiontech/sqle/releases
數據審覈插件開發文檔 https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章