背景:
环境及系统 | 集群及版本 | 配置 |
---|---|---|
数据库环境 | 3节点MGR集群 | primary节点 |
操作系统 | CentOS Linux release 7.9.2009 (Core) | 8核16G |
目前主库数据库使用内存达到88%左右,其他的2从库内存使用率40%左右,通过观察主库内存使用率每天都有小幅度上升趋势。但是,innodb_buffer_pool_size才设置8G, 怀疑mysql客户端连接的线程断开后,内存不能正常释放.
把线程相关的内存参数调整小一些
mysqlsort_buffer_size read_buffer_size read_rnd_buffer_size join_buffer_size binlog_cache_size tmp_table_size
重启mysql实例后,释放内存,运行一段时间,问题依然存在,没有得到解决。
编写查看内存脚本如下:
bash[root@wtj1vpdbmgnt01 shell]# cat check_mem_alloc.sh
#!/bin/bash
# ----------------------------------------------------------------
# Copyright © 2024 Openserv Ltd. All rights reserved.
# FileName : check_mem_alloc.sh
# Author : dba
# Mail : [email protected]
# Version : v1.0.0
# CreateTime : 2024-06-06 10:55:19
# COPYRIGHT : Copyright ©2024 - 开源服务
# Description: Welcome Use The Script.
# ----------------------------------------------------------------
# 修改为自已数据库实例的账号和密码等信息
/acdata/data/mysqlsoft3306/bin/mysql -h 10.3.8.112 -u root -p'xxxxxx' -P 3306 -e "show variables; show status" | awk '
{
VAR[$1]=$2
}
END {
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"] + VAR["net_buffer_length"]
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 "| %40s | %15.3f MB |\n", "net_buffer_length", VAR["net_buffer_length"]/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"
}'
按照脚本计算实例当前会话的最大的连接数为80,最大内存使用应该是8G,而现在mysqld占用的内存达到10G.
mysqlSELECT SUBSTRING_INDEX(event_name,'/',2) AS code_area, 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; mysql> SELECT SUBSTRING_INDEX(event_name,'/',2) AS -> code_area, 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; +---------------------------+---------------+ | code_area | current_alloc | +---------------------------+---------------+ | memory/innodb | 6.45 GiB | | memory/group_rpl | 1024.00 MiB | | memory/performance_schema | 278.82 MiB | | memory/temptable | 71.00 MiB | | memory/sql | 63.23 MiB | | memory/mysys | 12.23 MiB | | memory/mysqld_openssl | 2.87 MiB | | memory/mysqlx | 3.44 KiB | | memory/myisam | 696 bytes | | memory/csv | 88 bytes | | memory/blackhole | 88 bytes | | memory/vio | 16 bytes | +---------------------------+---------------+ 12 rows in set (0.01 sec)
注意
有些怀疑是不是有内存泄漏的问题,去官方也没有找到此版本内存泄漏的相关问题
最后,使用大绝招,逼mysql就范。
简言之,就是调用glibc申请的内存使用完毕后,归还给OS时没有被正常回收,而变成了碎片,随着碎片的不断增长,就能看到mysqld进程占用的内存不断上升。这时,可以调用函数主动回收释放这些碎片。
bash
# gdb --batch --pid `pidof mysqld` --ex 'call malloc_trim(0)'
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
45305 mysql 20 0 28.4g 5.2g 8288 S 2.7 17.0 64:56.82 mysqld
这就像是在InnoDB表中产生太多碎片后,主动执行OPTIMIZE TABLE重建表的做法。
bash[root@wyvpjhsql01 ~]# gdb --batch --pid `pidof mysqld` --ex 'call malloc_trim(0)'
[New LWP 12846]
[New LWP 32443]
[New LWP 15459]
[New LWP 32563]
[New LWP 14120]
[New LWP 24868]
[New LWP 2599]
[New LWP 1819]
[New LWP 32141]
[New LWP 20832]
[New LWP 20730]
[New LWP 20581]
[New LWP 30140]
[New LWP 29796]
[New LWP 29630]
[New LWP 17314]
[New LWP 16350]
[New LWP 14404]
[New LWP 14402]
[New LWP 2256]
[New LWP 2254]
[New LWP 1712]
[New LWP 1710]
[New LWP 1631]
[New LWP 1599]
[New LWP 1597]
[New LWP 1596]
[New LWP 1595]
[New LWP 1110]
[New LWP 12170]
[New LWP 31006]
[New LWP 12831]
[New LWP 12766]
[New LWP 12196]
[New LWP 429]
[New LWP 31775]
[New LWP 30259]
[New LWP 28717]
[New LWP 28519]
[New LWP 28353]
[New LWP 28352]
[New LWP 28257]
[New LWP 27899]
[New LWP 27662]
[New LWP 27575]
[New LWP 27545]
[New LWP 27514]
[New LWP 27498]
[New LWP 27492]
[New LWP 27491]
[New LWP 27490]
[New LWP 27461]
[New LWP 27452]
[New LWP 27451]
[New LWP 27449]
[New LWP 27438]
[New LWP 27437]
[New LWP 27435]
[New LWP 27434]
[New LWP 27433]
[New LWP 27430]
[New LWP 27429]
[New LWP 27428]
[New LWP 27424]
[New LWP 27422]
[New LWP 27421]
[New LWP 27420]
[New LWP 27419]
[New LWP 27417]
[New LWP 27409]
[New LWP 27408]
[New LWP 18138]
[New LWP 18136]
[New LWP 18135]
[New LWP 18134]
[New LWP 18133]
[New LWP 18132]
[New LWP 18131]
[New LWP 11498]
[New LWP 11444]
[New LWP 11441]
[New LWP 11440]
[New LWP 11439]
[New LWP 11435]
[New LWP 11434]
[New LWP 11433]
[New LWP 11432]
[New LWP 11429]
[New LWP 11428]
[New LWP 11427]
[New LWP 11426]
[New LWP 11425]
[New LWP 11424]
[New LWP 11423]
[New LWP 11422]
[New LWP 11421]
[New LWP 11420]
[New LWP 11419]
[New LWP 11418]
[New LWP 11417]
[New LWP 11416]
[New LWP 11415]
[New LWP 11414]
[New LWP 11413]
[New LWP 11412]
[New LWP 11411]
[New LWP 11410]
[New LWP 11409]
[New LWP 11408]
[New LWP 11407]
[New LWP 11406]
[New LWP 11405]
[New LWP 11404]
[New LWP 11403]
[New LWP 11402]
[New LWP 11401]
[New LWP 11400]
[New LWP 11399]
[New LWP 11398]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
0x00007fc1a23bdddd in poll () from /lib64/libc.so.6
$1 = 1
[Inferior 1 (process 11385) detached]
执行后发现内存使用率明显降下来了
js[root@wyvpjhsql01 ~]# free -m
total used free shared buff/cache available
Mem: 15884 11831 719 63 3334 3659
Swap: 8187 585 7602
至此问题告一段落,后续继续进行跟踪观察。
本文作者:Kevin@灼华
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!