一、问题现象
- 内存占用异常:通过
top
命令发现mysql进程(mysqld
)占用了90.7%的物理内存(56.5g/62g)。 - 系统负载:cpu使用率较低(1.3%),但内存几乎耗尽。
二、核心排查步骤
1. 参数检查
- mysql版本:8.0.39(未开启慢查询日志)。
- 关键内存参数:
show variables like 'innodb_buffer_pool_size'; -- 12g(配置较低,建议调整为总内存的70%~80%) show variables like 'tmp_table_size'; -- 16m(临时表内存限制过小)
- 临时文件路径:
/tmp
(建议改为专用目录以避免性能问题)。
2. 内存使用分析
全局内存统计:
select sum(cast(replace(current_alloc,'mib','') as decimal(10,2))) from sys.memory_global_by_current_bytes where current_alloc like '%mib%';
结果:总内存使用约1933.69mb。
分事件内存占用:
select event_name, sys.format_bytes(current_number_of_bytes_used) from performance_schema.memory_summary_global_by_event_name order by current_number_of_bytes_used desc limit 10;
关键发现:
memory/innodb/buf_buf_pool
占用13.29gb(innodb缓冲池)。memory/group_rpl/gcs_xcom::xcom_cache
占用1024mb(复制相关缓存)。
用户级内存统计:
select user, event_name, current_number_of_bytes_used/1024/1024 as mb_used from performance_schema.memory_summary_by_account_by_event_name where host <> "localhost" order by mb_used desc limit 10;
发现:特定用户(如
zqzh
)在memory/temptable/physical_ram
中占用65mb。
3. 存储过程/函数/视图检查
存储过程与函数:
select routine_schema, routine_type from information_schema.routines where routine_schema not in ('mysql','information_schema','performance_schema','sys');
结果:多个业务库存在大量存储过程和函数(如
bpc
、bsc
等)。视图与触发器:
select table_schema, count(table_name) from information_schema.views; select trigger_schema, count(*) from information_schema.triggers;
结果:视图和触发器数量较少,非主要内存消耗源。
4. 操作系统级检查
进程内存占用:
ps -eo user,pid,vsz,rss | grep mysqld
结果:
mysqld
进程虚拟内存(virt)96.2g,物理内存(res)56.5g。内存映射分析:
pmap -d <mysql_pid> | tail -1
关键指标:
writeable/private
:进程实际占用的私有内存(持续增长可能提示内存泄漏)。
透明大页(thp)检查:
cat /sys/kernel/mm/transparent_hugepage/enabled
结果:thp处于开启状态(可能导致内存分配效率低下)。
三、解决方案
1. 调整mysql配置
- 增加innodb缓冲池:
innodb_buffer_pool_size = 48g -- 根据总内存(62g)调整为77%
- 优化临时表内存:
tmp_table_size = 256m max_heap_table_size = 256m
2. 关闭透明大页(thp)
- 临时关闭:
echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag
- 永久关闭:
在/etc/rc.local
中添加:if test -f /sys/kernel/mm/transparent_hugepage/enabled; then echo never > /sys/kernel/mm/transparent_hugepage/enabled fi if test -f /sys/kernel/mm/transparent_hugepage/defrag; then echo never > /sys/kernel/mm/transparent_hugepage/defrag fi
3. 优化查询与存储过程
- 分析慢查询:开启慢查询日志,定位低效sql。
- 减少存储过程依赖:将复杂逻辑移至应用层,避免存储过程内存泄漏。
4. 硬件与环境优化
- 增加物理内存:若业务需求增长,考虑升级服务器内存。
- 迁移临时文件目录:将
tmpdir
设置为专用高速存储路径。
四、总结
- 核心问题:mysql内存使用率高主要由innodb缓冲池配置不足、thp机制效率低下及存储过程/函数内存占用引起。
- 解决重点:调整缓冲池大小、关闭thp、优化查询逻辑。
- 后续监控:通过
sys.memory_global_by_current_bytes
和pmap
持续观察内存变化。
通过以上步骤,可显著降低mysql内存占用并提升稳定性。
附:为了解决高内存占用问题,可以采取以下措施
- 仔细审查并调整mysql的其他内存相关配置项,确保它们合理且与系统资源匹配。
- 监控并分析mysql的实际内存使用情况,使用如show engine innodb status;和performance_schema来获取更详细的内存使用报告。
- 考虑调整操作系统的内存管理策略,比如调整thp设置或使用/proc/sys/vm/swappiness来调整内存交换行为。
- 如果确定内存分配合理,且应用确实需要这么多内存来保证性能,那么可能需要接受较高的内存占用率作为正常现象,或考虑增加服务器物理内存。
到此这篇关于mysql内存使用率高问题排查过程以及解决方案的文章就介绍到这了,更多相关mysql内存使用率高问题内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论