一 簡介: mysql基於linux的內存分析
二 關鍵指標定義
1 底層分配和釋放內存
1 使用C標准庫的malloc()或者mmap(),就可以在堆和文件映射段分配內存了,通過free()或者ummap()進行釋放
2 top關注進程
virt是虛擬內存占用量,即便沒有使用,只要申請過,就會算進去,mysql申請的virt memory是不會釋放的
res 是實際占用內存,但是不包含共享內存和swap占用
share 是共享內存大小
mem% 是進程占用物理內存的百分比
注意 通常情況下虛擬內存的占用會遠遠大於真實內存,但是如果相等,就標明申請的全部用到
3 free -m
1 Buffer(緩沖區) 是對磁盤數據的緩存,用來合並多次小寫成為一次大寫
2 Cache(緩存) 是文件數據的緩存,用來進行文件的讀寫,數據庫針對cache的使用率非常高,因為都是從文件讀取數據到內存的
三 mysql層
全局級別 innodb_buffer_pool,innodb_log_buffer_size
會話級別 session
1 查詢相關變量 sort_buffer_size,join_buffer_size,tmp_table_size等
2 事務相關變量 binlog_cache_size
3 會話相關變量 thread_stack
四 常見問題場景
場景1
描述 linux使用了全部內存,並且占用了swap空間,甚至導致了oom-killer
場景2
描述 linux使用了還有大量剩余內存,但是卻使用了swap空間
場景3
描述 linux使用了全部內存,並且占用了swap空間,但是與場景1不同點在於,mysql的innodb_buffer_pool設置的非常少.但是通過top卻發現大量的內存被mysql申請占用
五 通用解決方式
1 加大內存,innodb_buffer_pool,拆分數據庫 應對場景1(內存使用不足)
2 可能是由於numa導致的解決方式有以下幾種,應對場景2(由於numa問題導致)
1 mysql配置文件添加 innodb_numa_interleave=on
2 Linux Kernel啟動參數中加上numa=off
3 進行問題排查
1 pmap -d 看一下進程的內存情況,發現anoa的量很大(anoa代表進程主動申請內存)
2 打開mysql關於內存使用的統計
update performance_schema.setup_instruments set enabled = 'yes' where name like 'memory%'
3 應該是由於thread導致的,所以根據thread進行分析具體占用(5.7)
具體語句
1 select thread_id,event_name, SUM_NUMBER_OF_BYTES_ALLOC from memory_summary_by_thread_by_event_name order by SUM_NUMBER_OF_BYTES_ALLOC desc limit 20; 進行定位具體thread_id
2 select * from threads where thread_id=thread 定位具體線程
4 進行線程的具體分析
5 補充一個網上案例
原因插件代碼在使用cursor執行SQL以后, 沒有close......