常見誤區:設定 innodb_buffer_pool_size=8G,以為啟動瞬間佔用 8G 物理內存。實際上 MySQL 啟動時僅在虛擬地址空間預留範圍,首次寫入頁時才通過缺頁中斷映射到物理內存。
malloc / mmap 分配虛擬地址空間,返回指針。top 顯示的 VIRT 會很大,RES 隨實際使用緩慢增長。-- 物理 16G + Swap 8G
-- 程序 A 已 malloc 22G(未實際用)
-- MySQL 啟動 innodb_buffer_pool_size=8G(虛擬分配成功)
-- A 開始大量寫入,物理+Swap 僅剩 2G
-- MySQL 也開始寫入,Swap 耗盡 -> OOM Killer 啟動
-- OOM 選擇佔用物理內存最多的進程殺掉(通常是 MySQL)
/proc//oom_score :分數越高越易被殺。echo -1000 > /proc//oom_score_adj 保護關鍵進程(不推薦常規使用)。vm.swappiness=1。pmap -x 或 cat /proc//smaps 看實際物理佔用。innodb_large_prefix=ON + OS 配置 HugePages,減少頁表開銷、鎖定內存防 Swap。memory.limit_in_bytes 略大於 Buffer Pool,避免容器 OOM 殺掉 MySQL。innodb_buffer_pool_size 是虛擬地址空間預留,物理內存按需分配。生產環境務必按物理內存紅線規劃,留足餘量給 OS 與其他進程,防止 OOM Killer 誤殺 MySQL 導致不可用。