MySQL記憶體管理,記憶體分配器和作業系統

CloudQuery發表於2020-10-14

導讀
作者:Sveta Smirnova
翻譯:鄭志江
校對:徐晨亮
原文 :MySQL Memory Management, Memory Allocators and Operating System

本文涉及連結在文末展示

當使用者使用任何軟體(包括MySQL)碰到記憶體問題時,我們第一反應就是記憶體洩漏。正如這篇文章所示,其實並不總是這樣。

這篇文章闡述一個關於記憶體的bug。

所有percona所支援的客戶都有獲得bug修復的資格,但他們也有不同的選擇。比如,vip客戶在軟體補丁正式釋出之前就可以獲得hotfiix版本,高階客戶甚至不需要使用percona的軟體,我們也可以為他們把補丁推到上游。但對於與percona產品來說,所有支援等級都有權得到bug修復。

即便如此,這並不意味著我們會修復所有的意外情況,即使我們接受這種情況為一個有效bug。做出這樣的決定的原因之一可能是這個意外情況雖然很明確是錯誤的,但對於percona產品本身來說確實一個產品需求

作為學習案例的一個bug

最近一個很好的案例是 PS-5312<連結3>——這個bug可在上游復現並被記錄在bugs.mysql.com/95065<連結4>。

這個報告闡述了一種情況,當訪問InnoDB的全文索引的時候會導致記憶體使用量增長。這種情況出現在一些全文索引的查詢,記憶體會持續增長直到達到最大值,並且很長時間不會釋放。

來自Percona工程團隊的Yura Sorokin研究表明,這種情況並不屬於記憶體洩漏範疇。

當InnoDB解析一個全文查詢時,它會在fts_query_phrase_search函式中建立一個記憶體堆,這個堆可能增長到80M。另外,這個過程還會使用到大量非連續塊(mem_block_t)進而產生的記憶體碎片。

在函式出口,這些記憶體堆會被釋放。InnoDB會為其分配的每一個塊做這個操作。在函式執行結束時,呼叫一個記憶體分配器庫中的free()操作,比如malloc或者jemalloc。從MySQL本身來看,這都是沒問題的,不存在記憶體洩漏。

然而,free()函式被呼叫時確實應該釋放記憶體,但不需要將其返回給作業系統。如果記憶體分配器發現這些記憶體塊馬上還需要被用到,則會將他們保留住繼續用於mysqld程式。這就解釋了為什麼mysqld在完成工作及釋放記憶體都結束後還會佔用大量記憶體。

這個在實際生產中並不是一個大問題,按道理不應該造成任何事故。但是如果你需要更快地將記憶體返回給作業系統,你可以嘗試非傳統的記憶體分配器,類似jemallolc。它被證明可以解決PS-5312<連結5>的問題。

另一個改善記憶體管理的因素是cpu核心數量:在測試中,cpu核數越多,記憶體返回給作業系統的速度會越快。這可能是你擁有多個CPU,而其中一個可專門用作記憶體分配器釋放記憶體給作業系統。

正如我們的工程師Yura Sorokin所發現的一樣,下面兩點闡述了InnoDB全文索引的早期實現引入了這個缺陷:

5.6版本MySQL最早對InnoDB WL全文索引功能引入的介紹:#5538: InnoDB全文搜尋支援 – https://dev.mysql.com/worklog/task/?id=5538

實現WL #5538 InnoDB全文搜尋支援與合併 - - 也存在同樣的問題問題

修復方法

我們有兩種方法來修復這個問題:

1.修改InnoDB全文索引的實現

2.使用自定義記憶體庫,例如jemalloc

這兩種方法都有各自的優缺點。

方法1 :意味著我們引入了與軟體上游不相容性的風險,這可能會導致新版本中出現未知的錯誤。也意味著徹底重寫InnoDB全文索引部分程式碼,這在使用者們使用的GA版本中是有風險的。

方法2 則意味著我們可能會命中一些jemalloc庫中專門為效能設計但不是最安全的記憶體分配的bug。

因此我們不得不在這兩個並不完美的方法中選擇一個。

鑑於方法一可能導致percona服務與上游的不相容,我們更傾向於用方法二來解決問題,並期待著上游修復這個bug。

結論

如果發現mysqld程式佔用記憶體很高,並不代表一定是記憶體洩漏。我們可以在Performance Schema中使用記憶體檢測來了解程式是如何使用已分配的記憶體。也可以嘗試替換記憶體庫來更好地處理記憶體分配與釋放。關於LD_RELOAD如何配置,請查閱MySQL使用者手冊對應頁面 mysqld-safe<連結6>和using-system<連結7>。

連結1:
連結2:
連結3:
連結4:https://www.percona.com/blog/2019/05/02/mysql-memory-management-memory-allocators-and-operating-system/
連結5:
連結6:https://dev.mysql.com/doc/refman/8.0/en/mysqld-safe.html
連結7:https://dev.mysql.com/doc/mysql-installation-excerpt/8.0/en/using-systemd.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69985270/viewspace-2726783/,如需轉載,請註明出處,否則將追究法律責任。

相關文章