Mysql

為什麼在有足夠 RAM 的情況下 MySQL 傾向於使用越來越多的交換?

  • October 20, 2020

我有一個 64GB RAM 和 64GB 交換的伺服器。它執行 MySQL 8.0.19 和幾個 php 腳本。

這是我的配置:

innodb_buffer_pool_size=40G
innodb_buffer_pool_instances=4
innodb_buffer_pool_chunk_size=10G
sync_binlog=0
innodb_log_file_size=1G
innodb_ft_result_cache_limit=4000000000
max_heap_table_size=4G
tmp_table_size=4G
innodb_online_alter_log_max_size=512M
range_optimizer_max_mem_size=0
performance_schema="OFF"

此伺服器用於繁重計算,最多同時執行 5 個腳本,無使用者。

當某些腳本本身需要大量 RAM 的極少數情況下,需要進行巨大的交換。

伺服器工作越多,MySQL 嘗試消耗的記憶體就越多。如果我在幾週內不重新啟動它,最終會消耗 90GB 的總記憶體(~60RAM + ~30 交換)。所有這些都會大大降低性能。

目前我不知道除了簡單重啟之外的任何解決方案。它清除了整個交換空間,並使 MySQL 重新啟動,消耗約 40GB RAM。

你有什麼想法如何讓 MySQL 不使用 swap 那麼多嗎?當某些 PHP 腳本分配過多的 RAM 並將 MySQL 的記憶體推入交換空間時,可能會發生這種情況,但是一旦該程序完成,MySQL 就不會像我認為的那樣釋放交換空間。

是的,您可以通過使 MySQL 使用巨大的記憶體頁面來使 MySQL 不使用盡可能多的交換。巨大的頁面是不可交換的。

在 my.cnf 中,

$$ mysqld $$部分:

large-pages = 1

需要額外的作業系統級別配置。例如:

groupadd -g 630 hugetlb
usermod -G hugetlb mysql
sysctl -w vm.nr_hugepages = 20480
sysctl -w vm.hugetlb_shm_group = 630

您可能需要稍微增加 nr_hugepages,在它開始時查看日誌以尋找何時不再需要增加的線索。

此外,10GB 的緩衝池塊大小大得離譜。把它註釋掉。此外,緩衝池實例的最佳值是每個實例 1GB 到 2GB,因此對於 40GB 緩衝池,設置為 40 比設置為 4 更合適。

最後——如果你的 PHP 腳本可以使用超過 40GB 的 RAM,我敢說你需要解決這個問題。除非您確實需要一次處理 40GB 記憶體中的數據,否則幾乎可以肯定有更好的方法。

這些都是多餘的;不要將它們設置為超過 RAM 的 1%:

max_heap_table_size=4G
tmp_table_size=4G

如果您向我們展示查詢和SHOW CREATE TABLE.

查看您的 PHP 程式碼是否在ini_set("memory_limit",...). 即使 PHP 佔用記憶體,作業系統也可能選擇 MySQL 進行交換。

引用自:https://dba.stackexchange.com/questions/278099