內存分配算法配置及查詢
lsof -p `pidof mysqld` | grep -i malloc
返回空說明使用默認GLIBC內存分配算法
返回libtcmalloc_minimal說明使用GOOGLE的tcmalloc算法
返回libjemalloc說明使用jemalloc算法
若使用默認GLIBC內存分配算法,則可以查詢下當前內存碎片化情況
gdb -ex "call (void) malloc_stats()" --batch -p $(pidof mysqld)
上述命令執行完成后,會將內存使用情況打印到 MySQL 錯誤日志
將上述輸出存入臨時文件 tmp_mem_malloc.txt ,計算分配給 MySQL 內存和 MySQL 使用內存如下:
awk '{if($1 == "system") total+=$NF; else if ($1 == "in") used+=$NF }END{print total/1024/1024/1024,used/1024/1024/1024}' tmp_mem_malloc.txt
total和used相差越大,說明內存碎片化越嚴重
內存buffer參數配置最大占用計算
select VARIABLE_NAME,VARIABLE_VALUE/1024/1024 "size_MB/num" from performance_schema.global_variables where VARIABLE_NAME in ('key_buffer_size','query_cache_size', 'tmp_table_size','innodb_buffer_pool_size','innodb_additional_mem_pool_size','innodb_log_buffer_size','sort_buffer_size','read_buffer_size','read_rnd_buffer_size','join_buffer_size','thread_stack','binlog_cache_size')
union all
select VARIABLE_NAME,VARIABLE_VALUE from performance_schema.global_variables where VARIABLE_NAME in ('max_connections');
內存已經OOM過問題診斷
dmesg -Tx | grep -i "oom"
dmesg -Tx | grep -i "Dec 25"
dmesg -Tx > dmesg.log.20221227
oom日志中的rss為程序實際使用物理內存,單位為4kB內存頁,換算為GB=rss*4/1024/1024
內存管理優化
MySQL 8.0.28版本中引入的一個新特性,即監控和限制各個連接(會話)的內存消耗,以避免因執行低效SQL而消耗過多內存,從而減少被操作系統OOM(Out of Memory)kill的風險。
-
新特性引入:MySQL 8.0.28版本開始支持監控和限制每個連接的內存消耗。
-
系統選項設置:
global_connection_memory_tracking = 1:開啟全局或會話級別的內存消耗跟蹤。Global_connection_memory:系統狀態變量,用于查看所有連接消耗的內存總量。
-
內存統計更新頻率:
connection_memory_chunk_size:控制內存統計更新頻率,默認值為8KB。
-
內存使用限制:
connection_memory_limit:定義每個會話連接可使用的內存上限,默認值極大,實際上等于沒有限制。如果需要,可以調低這個值以限制內存使用。
-
SQL內存消耗評估:
- 通過調整
connection_memory_limit的值,可以評估一條SQL可能消耗的內存量。如果SQL消耗的內存超過限制,連接會被關閉。
- 通過調整
-
內存釋放:
- SQL執行完畢后,相應的內存會立即釋放,只保留維持會話連接所需的基本內存。
-
權限與內存限制:
- 普通用戶執行SQL受到內存使用上限的約束,而具有SUPER權限的用戶(如root)則不受此限制。
-
性能影響:
connection_memory_chunk_size設置得太小可能會頻繁更新內存統計,影響系統性能;設置得太大則可能導致OOM問題。