技術分享 | 我的內存去哪兒?生產實踐

作者:秦福朗

愛可生 DBA 團隊成員,負責項目日常問題處理及公司平臺問題排查。熱愛 IT,喜歡在互聯網裡暢遊,擅長攝影、廚藝,不會廚藝的 DBA 不是好司機,didi~

本文來源:原創投稿

*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。

一、問題背景

業務反饋,數據庫最近總是隔一段時間連接失敗,過一會又沒事了,一天能發生了 2、3 次,後來發現和主機傳統大頁的配置有關,具體原因是什麼,請繼續看。

二、環境背景:

MySQL 5.6.25

vmware 虛擬機 CentOS 7.1

CPU 32C

內存 64G

innodb_buffer_pool_size = 48G


三、排查過程

1、首先查看了 mysql uptime 發現時間在今天,說明有過重啟。


2、查看當前內存 cpu 的使用:

使用 free 查看系統 64G 內存,used 使用了 61G+,還剩下 200 多 M 的 free,buffer/cache 也不多,使用 top 查看 MySQL RES 佔用 20 多 G 左右。

使用 numa 查看當前 numa 分配:

技術分享 | 我的內存去哪兒?生產實踐

發現每個 node 的剩餘內存均不多。


3、因為懷疑重啟,所以查看下系統日誌,發現了重啟原因

技術分享 | 我的內存去哪兒?生產實踐

發現 mysqld 發現了 OOM(什麼是 OOM,可以在本公眾號搜索 OOM),且一天發生了 2、3 次和業務反饋是對的上的。

繼續看,

此處可看到在發生 OOM 時,MySQL 佔用系統內存 aron-rss 大約為 22G。

計算 rss 的數量(此處為頁數),每頁為 4K,計算完成近大約為 22.1G。

技術分享 | 我的內存去哪兒?生產實踐

那麼問題來了,

主機內存 64G,實際才使用了 22G 多,怎麼會發現生 OOM,free used 使用了 61G,那麼我的內存去哪了


4、查看 /proc/meminfo

技術分享 | 我的內存去哪兒?生產實踐

看上面發現和我們用 free 和 top 看到的值是一樣的

繼續看,

在傳統大頁這裡發現了問題,

在這裡,傳統大頁 Total 配置了 20000,FREE 也為 20000,說明配置了大頁但沒在使用,hugepagesize 為 2M,這一塊預留的就是 40G 大頁內存。

Tips:

“大內存頁”也稱傳統大頁、大頁內存等有助於 Linux 進行虛擬內存的管理,標準的內存頁為 4KB,這裡使用“大內存頁”最大可以定義 1GB 的頁面大小,在系統啟動期間可以使用“大內存頁”為應用程序預留一部分內存,這部分內存被佔用且永遠不會被交換出內存,它會一直保留在那裡,直到改變配置。(詳細介紹請看下面鏈接官方解釋)


5、那麼這 40G 大頁內存是分配給誰的呢?

查詢一下:

<code>shell> 

/proc/sys

/vm/hugetlb

_shm_group

27

shell> id

27

uid=

27

(mysql) gid=

27

(mysql) groups=

27

(mysql)/<code>

hugetlb_shm_group 文件裡填的是指定大頁內存使用的用戶組 id,這裡查看到是 MySQL 組 id,那既然是給 MySQL 的為什麼 free 等於 total,並且 mysql 還只有 20 多 G 實際使用內存呢?

原來在 MySQL 中還有專門啟用大內存頁的參數,在 MySQL 大內存頁稱為 large page。

技術分享 | 我的內存去哪兒?生產實踐


6、查看 MySQL 配置文件

技術分享 | 我的內存去哪兒?生產實踐

發現配置文件中確實有 large-page 配置,但出於禁用狀態。

後與業務確認,很早之前確實啟用過 mysql 的 large page,不過後面禁用了。排查到這基本就有了結論。


四、結論

這套環境之前開啟了 20000 的大內存頁,每頁大小為 2MB,佔用了 40G 內存空間,給 MySQL 使用,並且 MySQL 開啟了 large page,但後來不使用的時候,只關閉了 MySQL 端的 large page 參數,但沒有實際更改主機的關於大內存頁的配置,所以導致,實際上主機上的還存在 20000 的大內存頁,並且沒在使用,這一部分長期空閒,並且其他程序不能使用。

所以 MySQL 在使用 20G 內存左右,整個主機內存就飽和了,然後在部分條件下,就觸發了 OOM,導致 mysqld 被 kill,但主機上又有 mysqld_safe 守護程序,所以又再次給拉起來,就看到了文章初的偶爾連接不上的現象。


五、後續操作

經過在本地測試,確實指定大頁之後會導致內存佔用,如果 MySQL 不配置,會空閒這部分內存,且模擬大業務的情況下會發生 OOM。

所以,在問題環境上:

通過移除 vm 相關參數,使被佔用的大內存頁釋放出來,MySQL 就沒再被 oom 過。


六、建議

1、MySQL 主機一般不必使用 hugepage,MySQL 自己處理 buffer pool 的分頁管理,不需要操作系統的參與;

2、建議在環境上線前,檢查一下主機內存的大內存頁分配,看是否有沒在使用的傳統大頁的存在,避免影響後續業務的使用。

附:參考資料

1、
https://docs.oracle.com/database/121/UNXAR/appi_vlm.htm#UNXAR391

2、
https://kerneltalks.com/services/what-is-huge-pages-in-linux/

3、
https://dev.mysql.com/doc/refman/5.6/en/large-page-support.html


分享到:


相關文章: