資料庫核心月報-2015/07-MySQL·社群動態·MySQL記憶體分配支援NUMA
NUMA 問題曾經一直是困擾DBA的一個大問題,早在 2010 年, 就有人給MySQL報了Bug#57241, 指出了MySQL在x86系統下存在嚴重的 “swap insanity” 問題。在NUMA架構越來越普遍的今天,這個問題越來越嚴重。
MySQL的 swap insanity 問題
有同學專門翻譯了Jeremy Cole關於 “swap insanity” 問題的文章,原文看這裡,
如果你沒空看的話,這裡簡單描述一下,就是當你把主機大部分記憶體分配給InnoDB時,你會發現明明作業系統還有很多記憶體,但是卻有很多記憶體被交換到了SWAP分割槽。
從這裡可以下載到一個測試的C程式碼,如果你有NUMA架構的伺服器,可以測試下不同分配方式的效能差異:
sudo -s
echo 2048 > /proc/sys/vm/nr_hugepages
echo 1000000000000 > /proc/sys/kernel/shmmax
# Node local allocation
for i in `seq 0 4 127`
do
./latency2001 -a $i -c $i -l 128M
done
# Allocate on memory on CPU 0
for i in `seq 0 4 127`
do
./latency2001 -a 0 -c $i -l 128M
done
有兩個方式可以解決這個問題:
1. 在Linux Kernel啟動引數中加上numa=off(這樣也會影響到其他程式使用NUMA);
2. 在mysqld_safe指令碼中加上“numactl –interleave all”來啟動mysqld。
當然如果跑多例項,我也用過直接繫結mysqld程式到某個numa節點的方式,不過這要求每個例項分配的記憶體不超過每個NUMA節點管理的記憶體。指令碼可以看這裡。
5年過去了,官方依然沒有解決這個Bug。但好訊息是,官方終於著手解決這個問題了,Stewart Smith 同學提交的Bug#72811,其Patch即將出現在MySQL 5.6.27, 5.7.9 版本之中。
程式碼層面解決NUMA問題
如果在程式碼層面徹底解決NUMA問題,那麼我們需要解決兩個問題:
1. 全域性記憶體應該採用interleave的分配方式分散在不同的numa node上;
2. 執行緒記憶體應該採用local的分配方式分配線上程執行的numa node上。
Linux 提供了 set_mempolicy()
函式可以用來設定程式的記憶體分配策略,其中預設的MPOL_DEFAULT策略就是在當前執行的節點上分配記憶體,而MPOL_INTERLEAVE策略則是跨所有節點來分配記憶體。這個函式的說明可以看這裡。
因此對於MySQL Server和InnoDB引擎都需要做修改:
1. 在mysqld_main()
入口設定 set_mempolicy(MPOL_INTERLEAVE, NULL, 0)
啟用全域性分配方式;
2. 在MySQL啟動完成之後設定set_mempolicy(MPOL_DEFAULT, NULL, 0)
啟用本地分配方式;
3. 在InnoDB入口時設定 set_mempolicy(MPOL_INTERLEAVE, NULL, 0)
啟用全域性分配方式;
4. 在Buffer Pool分配完成時設定 set_mempolicy(MPOL_DEFAULT, NULL, 0)
啟用本地分配方式。
MySQL 5.6.27, 5.7.9 釋出之後,將會增加一個 innodb_numa_interleave
引數來控制這個策略。innodb_numa_interleave
如果開啟,那麼將會按上面的策略來設定記憶體分配方式,如果關閉或者主機不支援NUMA,那麼還是按原來的方式分配。
我們一起期待新版本的釋出吧,媽媽再也不用擔心我的NUMA了!
相關文章
- 動態記憶體分配記憶體
- C++ 動態記憶體分配C++記憶體
- 動態分配記憶體地址(.NET)記憶體
- C++動態記憶體分配C++記憶體
- 簡單理解動態記憶體分配和靜態記憶體分配的區別記憶體
- C語言(動態記憶體分配)C語言記憶體
- oracle資料庫記憶體分配(sga和pga)Oracle資料庫記憶體
- C++ 指標動態記憶體分配C++指標記憶體
- 資料庫核心月報-2015/11-MySQL·特性分析·StatementDigest資料庫MySql
- Oracle資料庫開啟NUMA支援Oracle資料庫
- 核心記憶體分配常用函式使用記憶體函式
- 核心早期記憶體分配器:memblock記憶體BloC
- 資料庫核心月報-2015/09-MySQL·捉蟲動態·建表過程中crash造成重建表失敗資料庫MySql
- C++ 動態記憶體分配與名稱空間C++記憶體
- Pytorch視訊記憶體動態分配規律探索PyTorch記憶體
- 記憶體資料庫記憶體資料庫
- MySQL核心月報2015.03-MySQL·捉蟲動態·pidfile丟失問題分析MySql
- C語言malloc()函式:動態分配記憶體空間C語言函式記憶體
- 記憶體動態分配與釋放,malloc和new區別記憶體
- 智慧指標的模板,用來管理動態分配的記憶體指標記憶體
- MySQL記憶體管理,記憶體分配器和作業系統MySql記憶體作業系統
- MySQL OOM 系列一 Linux記憶體分配MySqlOOMLinux記憶體
- MySQL 配置InnoDB的記憶體分配器MySql記憶體
- MySQL • 原始碼分析 • 記憶體分配機制MySql原始碼記憶體
- mysql用於分配記憶體的引數MySql記憶體
- JavaScript記憶體分配JavaScript記憶體
- JVM記憶體分配JVM記憶體
- java記憶體分配Java記憶體
- Mongodb記憶體資料庫MongoDB記憶體資料庫
- 垃圾收集器與記憶體分配策略_記憶體分配策略記憶體
- 二維陣列的動態記憶體分配和釋放 (轉)陣列記憶體
- Go 語言社群新提案 arena,可優化記憶體分配Go優化記憶體
- 動態記憶體管理記憶體
- 資料揭祕“群社交”:2015年中國移動社群生態報告
- JVM 記憶體模型 記憶體分配,JVM鎖JVM記憶體模型
- 探索iOS記憶體分配iOS記憶體
- Java 記憶體分配策略Java記憶體
- java jvm 記憶體分配JavaJVM記憶體