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

MySQL OOM 系列(一):Linux 內存過度提交機制與 OverCommit 深度解析

     編輯:MySQL 綜合教學

前言

線上 4GB RDS 實例發生 OOM,MySQL 進程被 Kill。要破解此謎,必須先理解 Linux 內存分配的核心機制——OverCommit(過度提交)。本文從 malloc 行為差異、/proc/sys/vm/overcommit_memory 三種模式、用戶態驗證實驗三個維度,建立 Linux 內存分配心智模型。

一、malloc 的誤區與 Linux 現實

  • 傳統認知:malloc 失敗返回 NULL 表示物理內存+Swap 耗盡
  • Linux 事實:默認允許申請遠超物理內存+Swap 的虛擬地址空間,只有真正寫入(觸發缺頁中斷)時才分配物理頁

這是「樂觀分配」策略:假設應用申請後不會立即全量使用,提高內存利用率。

二、overcommit_memory 三種模式

值模式行為適用場景
0Heuristic(默認)內核啟發式算法:允許輕微過度提交,拒絕明顯超大請求;root 用戶額度更大通用生產環境
1Always Overcommit無條件允許,只受虛擬地址空間限制(32位 4GB、64位 ~16TB)科學計算、稀疏矩陣、嵌入式無 Swap
2Strict Overcommit禁止過度提交:CommitLimit = Swap + RAM × overcommit_ratio(默認 50%)嚴格合規、實時系統、無 Swap 環境
# 查看當前模式
cat /proc/sys/vm/overcommit_memory
# 查看 CommitLimit / Committed_AS
grep -i commit /proc/meminfo

三、驗證實驗:申請 vs 寫入

實驗環境

1GB RAM + 400MB Swap 虛擬機

程序 A:僅 malloc 不寫入

while (1) {
    p = malloc(1MB);
    if (!p) break;
    printf("Allocated %d MB\n", ++count);
}
// 結果:申請到 ~1.4GB(RAM+Swap)甚至更多才失敗

程序 B:malloc 後 memset 寫入

while (1) {
    p = malloc(1MB);
    if (!p) break;
    memset(p, 1, 1MB);  // 觸發缺頁中斷,真正分配物理頁
    printf("Allocated %d MB\n", ++count);
}
// 結果:申請到 ~1GB 左右(接近物理內存上限)即失敗或被 OOM Kill

結論

  • 虛擬內存(VIRT)≫ 物理內存(RSS)是常態
  • OverCommit 讓「申請」與「使用」解耦,但引入「兌付風險」

四、風險兌付:OOM Killer 機制預告

當物理內存+Swap 即將耗盡,內核必須犧牲進程釋放內存。下一篇將深入 oom_badness() 評分算法、oom_score_adj 調控、MySQL 如何成為「首選犧牲者」及規避策略。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved