mysql內存查閱 mysql內存分析


 【1】整體內存分析

該部分腳本轉自:https://blog.csdn.net/weixin_36114835/article/details/113210288

效果如下

 

#!/bin/sh

# you might want to add some user authentication here
mysql -e "show variables; show status" | awk '
{undefined
VAR[$1]=$2
}

END {undefined
MAX_CONN = VAR["max_connections"]
MAX_USED_CONN = VAR["Max_used_connections"]
BASE_MEM=VAR["key_buffer_size"] + VAR["query_cache_size"] + VAR["innodb_buffer_pool_size"] + VAR["innodb_additional_mem_pool_size"] + VAR["innodb_log_buffer_size"]
MEM_PER_CONN=VAR["read_buffer_size"] + VAR["read_rnd_buffer_size"] + VAR["sort_buffer_size"] + VAR["join_buffer_size"] + VAR["binlog_cache_size"] + VAR["thread_stack"] + VAR["tmp_table_size"]
MEM_TOTAL_MIN=BASE_MEM + MEM_PER_CONN*MAX_USED_CONN
MEM_TOTAL_MAX=BASE_MEM + MEM_PER_CONN*MAX_CONN

printf "+------------------------------------------+--------------------+\n"
printf "| %40s | %15.3f MB |\n", "key_buffer_size", VAR["key_buffer_size"]/1048576
printf "| %40s | %15.3f MB |\n", "query_cache_size", VAR["query_cache_size"]/1048576
printf "| %40s | %15.3f MB |\n", "innodb_buffer_pool_size", VAR["innodb_buffer_pool_size"]/1048576
printf "| %40s | %15.3f MB |\n", "innodb_additional_mem_pool_size", VAR["innodb_additional_mem_pool_size"]/1048576
printf "| %40s | %15.3f MB |\n", "innodb_log_buffer_size", VAR["innodb_log_buffer_size"]/1048576

printf
"+------------------------------------------+--------------------+\n" printf "| %40s | %15.3f MB |\n", "BASE MEMORY", BASE_MEM/1048576 printf "+------------------------------------------+--------------------+\n"
printf "| %40s | %15.3f MB |\n", "sort_buffer_size", VAR["sort_buffer_size"]/1048576 printf "| %40s | %15.3f MB |\n", "read_buffer_size", VAR["read_buffer_size"]/1048576 printf "| %40s | %15.3f MB |\n", "read_rnd_buffer_size", VAR["read_rnd_buffer_size"]/1048576 printf "| %40s | %15.3f MB |\n", "join_buffer_size", VAR["join_buffer_size"]/1048576 printf "| %40s | %15.3f MB |\n", "thread_stack", VAR["thread_stack"]/1048576 printf "| %40s | %15.3f MB |\n", "binlog_cache_size", VAR["binlog_cache_size"]/1048576 printf "| %40s | %15.3f MB |\n", "tmp_table_size", VAR["tmp_table_size"]/1048576
printf
"+------------------------------------------+--------------------+\n" printf "| %40s | %15.3f MB |\n", "MEMORY PER CONNECTION", MEM_PER_CONN/1048576 printf "+------------------------------------------+--------------------+\n" printf "| %40s | %18d |\n", "Max_used_connections", MAX_USED_CONN printf "| %40s | %18d |\n", "max_connections", MAX_CONN printf "+------------------------------------------+--------------------+\n" printf "| %40s | %15.3f MB |\n", "TOTAL (MIN)", MEM_TOTAL_MIN/1048576 printf "| %40s | %15.3f MB |\n", "TOTAL (MAX)", MEM_TOTAL_MAX/1048576 printf "+------------------------------------------+--------------------+\n" }'

【2】具體內存分析

(2.1)連接內存

SELECT ( @@read_buffer_size
+ @@read_rnd_buffer_size
+ @@sort_buffer_size
+ @@join_buffer_size
+ @@binlog_cache_size
+ @@thread_stack
+ @@tmp_table_size
+ 2*@@net_buffer_length
) / (1024 * 1024) AS MEMORY_PER_CON_MB;

【3】整體內存占用分析

(3.1)查看渠道與角度

從哪里開始排除MySQL內存泄漏問題?

假設這是一個Linux服務器,首先我們要 

檢查Linux操作系統和配置 :

  1. 檢查mysql錯誤日志和Linux日志文件(即/ var / log / messages或/ var / log / syslog)來識別崩潰。你可能會看到OOM Killer殺死MySQL的條目,可以使用“dmesg”來顯示相關的詳細信息。

  2. 檢查可用的RAM: free -g    cat / proc / meminfo

  3. 檢查哪些應用程序正在使用RAM: “top”或“htop”

  4. 檢查mysql配置: /etc/my.cnf 或general /etc/my* (including /etc/mysql/*等文件),MySQL可能正在運行不同的my.cnf(run ps  ax | grep mysql  )

  5. 運行 vmstat 5 5  以查看系統是否正在通過虛擬內存進行讀/寫以及是否正在進行交換

  6. 對於非生產環境,我們可以使用其他工具(如Valgrind,gdb等)來檢查MySQL的使用情況.

(3.2)檢查MySQL內部

我們也可以通過檢查MySQL內部來發現潛在的MySQL內存泄露。MySQL在很多地方都會有內存分配,尤其是在以下情況下:

現在我們可以檢查MySQL內部的東西來尋找潛在的MySQL內存泄漏。

MySQL在很多地方分配內存。特別:

  1. Table cache

  2. Performance_schema(運行: show engine performance_schema status ,並查看最后一行)。

  3. InnoDB(運行 show engine innodb status   並檢查緩沖池部分,為buffer_pool和相關緩存分配的內存)

  4. RAM中的臨時表(通過運行以下語句查找所有內存表: select * from information_schema .tables where engine ='MEMORY'  )

  5. Prepared statements。

不過,從MySQL 5.7版本開始,我們就可以在performance_schema中查看內存分配。那么,如何使用呢?

首先,我們需要啟用收集內存指標。Run:

UPDATE performance_schema.setup_instruments SET ENABLED='YES'WHERE NAME LIKE 'memory/%';

(3.3)常見內存使用查詢庫表

常見表

-- sys 庫
memory_by_host_by_current_bytes  
memory_by_thread_by_current_bytes
memory_by_user_by_current_bytes  
memory_global_by_current_bytes   
memory_global_total              

-- performance_schema 庫
memory_summary_by_account_by_event_name:賬號緯度的內存監控表
memory_summary_by_host_by_event_name:主機緯度的內存監控表
memory_summary_by_thread_by_event_name:線程維度的內存監控表
memory_summary_by_user_by_event_name:用戶緯度的內存監控表
memory_summary_global_by_event_name:全局緯度的內存監控表

內存監控表
在performance_schema庫下,提供多個維度的內存監控表,具體如下:

memory_summary_by_account_by_event_name:賬號緯度的內存監控表
memory_summary_by_host_by_event_name:主機緯度的內存監控表
memory_summary_by_thread_by_event_name:線程維度的內存監控表
memory_summary_by_user_by_event_name:用戶緯度的內存監控表
memory_summary_global_by_event_name:全局緯度的內存監控表
內存監控表均包括以下關鍵字段:

COUNT_ALLOC:內存分配次數
COUNT_FREE:內存回收次數
SUM_NUMBER_OF_BYTES_ALLOC:內存分配大小
SUM_NUMBER_OF_BYTES_FREE:內存回收大小
CURRENT_COUNT_USED:當前分配的內存,通過COUNT_ALLOC-COUNT_FREE計算得到
CURRENT_NUMBER_OF_BYTES_USED:當前分配的內存大小,通過SUM_NUMBER_OF_BYTES_ALLOC-SUM_NUMBER_OF_BYTES_FREE計算得到
LOW_COUNT_USED:CURRENT_COUNT_USED的最小值
HIGH_COUNT_USED:CURRENT_COUNT_USED的最大值
LOW_NUMBER_OF_BYTES_USED:CURRENT_NUMBER_OF_BYTES_USED的最小值
HIGH_NUMBER_OF_BYTES_USED:CURRENT_NUMBER_OF_BYTES_USED的最大值

(3.4)一個內存查詢SQL

select event_name, current_alloc, high_alloc
from sys.memory_global_by_current_bytes
where current_count > 0;

    

通常,分配內存時會提供代碼,所以在某些情況下搜索某些錯誤時,我們可能需要檢查 MySQL 源代碼。例如,對於在觸發器中過度分配內存的錯誤:

某些情況下搜索某些錯誤時,我們可能需要檢查MySQL源代碼。

例如,對於在觸發器中過度分配內存的錯誤

mysql> select event_name, current_alloc, high_alloc from memory_global_by_current_bytes where current_count > 0;

  

RAM中最大的塊通常是緩沖池,但存儲過程中的3G似乎也太高了。

根據MySQL源代碼文檔,SPHead表示存儲程序的一個實例,該程序可能是任何類型(存儲過程、函數、觸發器、事件)。

在這種情況下,就會有潛在的內存泄漏。此外,如果我們想要更清楚的知道MySQL內存情況,還可以得到一個更高級別的總報告。

select  substring_index( substring_index(event_name, '/', 2),  '/', -1 )  as event_type,
round(sum(CURRENT_NUMBER_OF_BYTES_USED)/1024/1024, 2) as MB_CURRENTLY_USED
from performance_schema.memory_summary_global_by_event_name group by event_type having MB_CURRENTLY_USED>0;

【4】常用內存SQL查詢

(4.1)總內存使用情況

SELECT SUBSTRING_INDEX(event_name,'/',2) AS code_area,
sys.format_bytes(SUM(current_alloc)) AS current_alloc FROM sys.x$memory_global_by_current_bytes
GROUP BY SUBSTRING_INDEX(event_name,'/',2)
ORDER BY SUM(current_alloc) DESC;

(4.2)查看線程占用

-- 具體線程
select THREAD_ID,EVENT_NAME,CURRENT_NUMBER_OF_BYTES_USED/1024/1024 'used_MB' 
from performance_schema.memory_summary_by_thread_by_event_name  
where CURRENT_NUMBER_OF_BYTES_USED>0 order by CURRENT_NUMBER_OF_BYTES_USED desc limit 30;

-- 線程總計
select sum(CURRENT_NUMBER_OF_BYTES_USED)/1024/1024 used_MB from memory_summary_by_thread_by_event_name;

 【5】

 

 

 

【參考文檔】

葉金榮:https://cloud.tencent.com/developer/article/1005397


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM