MySQL內(nèi)存使用率高且不釋放問題排查與總結(jié)
背景
生產(chǎn)環(huán)境mysql 5.7內(nèi)存占用超過90%以上,且一直下不來。截圖如下:
原因分析
1、確定mysql具體的占用內(nèi)存大小,通過命令:cat /proc/Mysql進(jìn)程ID/status查看
命令執(zhí)行后的結(jié)果比較多。
看到此處有必要延申一個(gè)知識(shí)點(diǎn)。innodb_buffer_pool_size
一、innodb_buffer_pool_size作用
InnoDB存儲(chǔ)引擎是MySQL中最常用的存儲(chǔ)引擎之一,它使用內(nèi)存緩存池(buffer pool)來緩存表中的數(shù)據(jù)和索引等信息。通過調(diào)整innodb_buffer_pool_size
參數(shù)的大小,可以控制InnoDB存儲(chǔ)引擎能夠利用的內(nèi)存空間,進(jìn)而影響其緩存的數(shù)據(jù)量和索引數(shù)量。
innodb_buffer_pool_size
設(shè)置的值較大時(shí),InnoDB存儲(chǔ)引擎能夠緩存更多的數(shù)據(jù)和索引,從而減少磁盤I/O的次數(shù),提高數(shù)據(jù)庫的訪問速度和性能。相反,如果緩存池設(shè)置過小,可能會(huì)導(dǎo)致頻繁的磁盤I/O操作,影響數(shù)據(jù)庫性能。
一般為物理內(nèi)存的60%-70%。
二、查看當(dāng)前配置的pool_size:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
發(fā)現(xiàn)結(jié)果是64G(配置文件也可查看),這里就發(fā)現(xiàn)問題:實(shí)際使用的內(nèi)存量比配置的量多出了60G左右。
暫且把64G當(dāng)成正常占用多出來的當(dāng)成異常占用分析。
三、performance schema內(nèi)存占用量分析
show engine performance_schema status;
查看結(jié)果中的最后一行。發(fā)現(xiàn)占用了200多M。
四、排查MySQL為當(dāng)前session會(huì)話分配的內(nèi)存
查看session級(jí)別的buffer和cache占用內(nèi)存大小。
show variables where variable_name in ('binlog_cache_size','join_buffer_size','read_buffer_size','read_rnd_buffer_size','sort_buffer_size')
結(jié)果如下:
總共加起來接近800M。
查看當(dāng)前活躍的連接數(shù)
SELECT * FROM information_schema.processlist WHERE command != 'Sleep';
結(jié)果顯示差不多只有9個(gè),加入每個(gè)都分配了全量的會(huì)話內(nèi)存,則差不多就是9G。(實(shí)際分配了多少需要根據(jù)當(dāng)前會(huì)話執(zhí)行的SQL判斷,比如有無使用到排序、有沒有使用join等)。上邊的算完頂多才10G,還有50多G的消耗,也就意味著還有其他的占用。
五、排查當(dāng)前臨時(shí)表占用內(nèi)存情況
查看tmp_table_size臨時(shí)表配置的內(nèi)存大?。?/h4>
線程級(jí)別參數(shù),實(shí)際限制從 tmp_table_size 和 max_heap_table_size 兩個(gè)變量的的值中取較小值。
show variables where variable_name in ('tmp_table_size','max_heap_table_size')
補(bǔ)充知識(shí)點(diǎn)一:臨時(shí)表
如果內(nèi)存中的臨時(shí)表超出限制,MySQL自動(dòng)將其轉(zhuǎn)換為磁盤上的MyISAM表。如果要執(zhí)行許多 GROUP BY查詢,可以增加tmp_table_size的值(或如有必要,也可以使用max_heap_table_size)。
執(zhí)行計(jì)劃中Extra字段包含有“Using temporary” 時(shí)會(huì)產(chǎn)生臨時(shí)表。
MySQL中臨時(shí)表主要有兩類,包括外部臨時(shí)表和內(nèi)部臨時(shí)表。外部臨時(shí)表是通過語句create temporary table...創(chuàng)建的臨時(shí)表,臨時(shí)表只在本會(huì)話有效,會(huì)話斷開后,臨時(shí)表數(shù)據(jù)會(huì)自動(dòng)清理。內(nèi)部臨時(shí)表主要有兩類,一類是information_schema中臨時(shí)表,另一類是會(huì)話執(zhí)行查詢時(shí),如果執(zhí)行計(jì)劃中包含有“Using temporary”時(shí),會(huì)產(chǎn)生臨時(shí)表。內(nèi)部臨時(shí)表與外部臨時(shí)表的一個(gè)區(qū)別在于,我們看不到內(nèi)部臨時(shí)表的表結(jié)構(gòu)定義文件frm。而外部臨時(shí)表的表定義文件frm,一般是以#sql{進(jìn)程id}_{線程id}_序列號(hào)組成,因此不同會(huì)話可以創(chuàng)建同名的臨時(shí)表。
查看當(dāng)前是否有臨時(shí)表產(chǎn)生
show global status like '%tmp%'
發(fā)現(xiàn)頻繁使用了臨時(shí)表,并且出現(xiàn)了因內(nèi)存臨時(shí)表不夠而使用到磁盤臨時(shí)表。由于臨時(shí)表占用的內(nèi)存具體大小可能無法準(zhǔn)確計(jì)算得出(因?yàn)槭褂猛陼?huì)回收,但是肯定存在當(dāng)前未被回收情況)。
補(bǔ)充知識(shí)點(diǎn)二:Mysql內(nèi)存管理模塊:
MySQL的內(nèi)存分配使用了系統(tǒng)glibc,而glibc本身的內(nèi)存分配算法存在缺陷,導(dǎo)致內(nèi)存釋放不完全,產(chǎn)生內(nèi)存碎片。可以通過gdb命令手動(dòng)回收內(nèi)存碎片:
gdb --batch --pid ‘pidof mysqld’ --ex 'call malloc_trim(0)';
但是在生產(chǎn)環(huán)境這個(gè)操作應(yīng)該謹(jǐn)慎使用。
此外,將MySQL的內(nèi)存分配機(jī)制修改為jemalloc,可以更好的釋放內(nèi)存。
六、問題總結(jié)和解決思路
總結(jié)一下MySQL內(nèi)存使用率高且不釋放的應(yīng)對(duì)方法:
- 繼續(xù)加大內(nèi)存(如果參數(shù)調(diào)無可調(diào)時(shí)選擇);
- 修改減小innodb_buffer_pool_size參數(shù)(犧牲一定innodb性能);
- 排查消耗內(nèi)存的慢SQL,及時(shí)優(yōu)化;
- 檢查相關(guān)session參數(shù)是否設(shè)置合理,比如join_buffer_size、query_cache_size是否設(shè)置過大;
- 使用gdb回收內(nèi)存碎片(生產(chǎn)環(huán)境謹(jǐn)慎操作):gdb --batch --pid ‘pidof mysqld’ --ex 'call malloc_trim(0)';
- 對(duì)MySQL進(jìn)程配置jemalloc內(nèi)存管理模塊;
- 配置讀寫分離,將讀操作應(yīng)用到從庫,減少對(duì)主庫的影響;
以上就是MySQL內(nèi)存使用率高且不釋放問題排查與總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于MySQL內(nèi)存使用率高且不釋放的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MySQL不可忽視的數(shù)據(jù)庫約束(維護(hù)數(shù)據(jù)秩序)
數(shù)據(jù)庫約束是數(shù)據(jù)庫管理中不可或缺的一部分,它們?cè)诰S護(hù)數(shù)據(jù)秩序、保證數(shù)據(jù)完整性和一致性方面發(fā)揮著重要作用,本文給大家介紹MySQL不可忽視的數(shù)據(jù)庫約束,感興趣的朋友一起看看吧2025-05-05MySQL基礎(chǔ)學(xué)習(xí)之字符集的應(yīng)用
這篇文章主要為大家詳細(xì)介紹了MySQL中字符集的相關(guān)使用,例如字符集的查詢與修改和比較規(guī)則等,文中的示例代碼講解詳細(xì),需要的可以參考一下2023-05-05windows下MySQL數(shù)據(jù)庫移動(dòng)到其它盤
大家好,本篇文章主要講的是windows下MySQL數(shù)據(jù)庫移動(dòng)到其它盤,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏2021-12-12mysql-canal-rabbitmq 安裝部署超詳細(xì)教程
這篇文章主要介紹了mysql-canal-rabbitmq 安裝部署超詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03centos7中如何利用crontab進(jìn)行mysql定時(shí)備份
crontab是一個(gè)命令,常見于Unix和類Unix的操作系統(tǒng)之中,用于設(shè)置周期性被執(zhí)行的指令,下面這篇文章主要給大家介紹了關(guān)于centos7中如何利用crontab進(jìn)行mysql定時(shí)備份的相關(guān)資料,需要的朋友可以參考下2022-02-02mysql字段為NULL索引是否會(huì)失效實(shí)例詳解
有很多人對(duì)null值是否走索引感覺很疑惑,所以下面這篇文章主要給大家介紹了關(guān)于mysql字段為NULL索引是否會(huì)失效的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05MySQL DATE_SUB()函數(shù)的實(shí)現(xiàn)示例
本文主要介紹了MySQL DATE_SUB() 函數(shù)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03mysql innodb 異常修復(fù)經(jīng)驗(yàn)分享
這篇文章主要介紹了mysql innodb 異常修復(fù)經(jīng)驗(yàn)分享,需要的朋友可以參考下2017-04-04