首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 調優基礎(二):Linux 記憶體管理、Swap 避坑與 InnoDB 緩衝池協同優化

     編輯:MySQL 綜合教學

MySQL 調優基礎(二):Linux 記憶體管理、Swap 避坑與 InnoDB 緩衝池協同優化

繼 CPU 篇後,本文深入 Linux 虛擬記憶體、頁面回收、Swap 機制、OOM Killer、HugePages、vm.swappiness、vm.dirty_ratio 等核心參數,結合 vmstat/sar/pmap/ps 實戰監控,構建 InnoDB 與 OS 記憶體協同優化體系。

一、Linux 虛擬記憶體模型

  • 進程見到的是虛擬地址空間(VIRT),映射至物理頁框(RES)或 Swap;
  • VIRT = RES + Swap(out) + 未映射保留;
  • Linux 激進使用空閒記憶體作 Page Cache (Disk Cache),free 顯示的 free 很小屬正常;
  • Swap 被使用不代表記憶體不足,只說明內核曾將冷頁換出;關鍵看持續 Swap in/out。

二、記憶體分配與回收機制

Buddy System 頁框分配

  • 以 4KB Page 為單位,維護 2^n 階空閒鏈表,合併分裂防碎片;
  • SLAB/SLUB 分配器在頁框上劃分小物件(inode、dentry、task_struct 等)。

Kswapd 守護進程與雙 LRU 列表

  • Active List:近期訪問頁;Inactive List:候選回收頁;
  • 頁面在 Active/Inactive 間升降級,最終從 Inactive 尾部回收;
  • 回收優先順序:Page Cache (文件頁) → Anonymous Pages (堆/棧);
  • vmstat -a 觀察 inact/active 佔比。

三、Swap 與 Page Out 關鍵區別

  • Page Out:單頁換出;
  • Swap Out:整個進程地址空間換出(極嚴重);
  • 監控指標:vmstat si/so (KB/s)、sar -B pgpgout/s (KB/s)、majflt/s (Major Page Fault/s)。

四、vm.swappiness 與 OOM Killer 避坑指南

OOM Score 調整保護 MySQL


# 查看當前 oom_score_adj (範圍 -1000~1000,越低越不易被殺)
cat /proc/$(pidof -s mysqld)/oom_score_adj

# 設置極低值保護 (舊介面 oom_adj 範圍 -17~15,-17=OOM_DISABLE)
echo -1000 > /proc/$(pidof -s mysqld)/oom_score_adj
# 或舊介面
echo -17 > /proc/$(pidof -s mysqld)/oom_adj

根治之道:保障物理記憶體充足 + vm.swappiness=1 + 監控 majflt/s,而非依賴 OOM 參數規避。

五、Page Cache 回寫調優:vm.dirty_ratio 族參數

內核版本vm.swappiness=0 行為建議值
舊內核 (≤2.6.32-302)盡量不 Swap,優先回收 Page Cache0
新內核 (≥2.6.32-303 / RHEL6.4+)觸發 OOM Killer 直接殺進程1 (不為 0,保留微量 Swap 緩衝)

MySQL 自身 innodb_flush_log_at_trx_commit/innodb_max_dirty_pages_pct 也控制髒頁,OS 與 DB 雙層協同調優。

六、實戰監控工具鏈

  1. vmstat 2:觀察 si/so、in/cs、wa;
  2. sar -B 2 10:pgpgout/s (Page Out)、majflt/s (Major Fault) 趨勢;
  3. free -m:關注 -/+ buffers/cache 行的 available;
  4. ps -mp -o THREAD,pmem,rss,vsz,tid,pid:MySQL 線程記憶體佔用;
  5. pmap -x :虛擬記憶體映射分佈(Heap/Stack/Shared Libs/Anonymous/Stack),定位記憶體洩漏;

七、HugePages:減少頁表開銷鎖定物理記憶體

  • 預設 4KB 頁,大記憶體 (如 64GB Buffer Pool) 頁表條目達百萬級,TLB Miss 多、頁表佔用大;
  • 配置 2MB/1GB HugePages,vm.nr_hugepages = 32768 (64GB/2MB);
  • MySQL 啟用:innodb_buffer_pool_chunk_size、large-pages (需鎖定記憶體權限 ulimit -l unlimited);
  • 代價:HugePages 不可 Swap、不可作他用、啟動預留失敗則 MySQL 無法啟動——務必壓測驗證。

八、記憶體調優決策樹

  1. 持續 so > 0 / pgpgout/s > 0 / majflt/s > 100 → 記憶體不足或 Swappiness 不當;
  2. 檢查 vm.swappiness、oom_score_adj、dirty_ratio;
  3. InnoDB 內部:innodb_buffer_pool_size 佔物理 70-80%、innodb_max_dirty_pages_pct=75、innodb_io_capacity 匹配磁盤;
  4. 若物理記憶體確不足 → 增加記憶體或架構分庫分表;
  5. 考慮 HugePages(專用 DB 伺服器、記憶體 ≥ 32GB、壓測驗證無風險)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
參數預設含義調優建議
vm.dirty_background_ratio10%髒頁達此比例,pdflush 異步回寫降至 5% 減少髒頁積壓,增加回寫頻率
vm.dirty_ratio20%髒頁達此比例,同步阻塞回寫降至 10-15% 避免寫入延遲抖動
vm.dirty_expire_centisecs3000 (30s)髒頁超時強制回寫視延遲容忍度調整
vm.dirty_writeback_centisecs500 (5s)pdflush 喚醒間隔降低可減少單次回寫量