暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

包拯断案 | 数据库内存被打满怎么破@还故障一个真相

万里数据库 2025-04-07
10


提问:作为DBA运维的你是否遇到过这些烦恼


1、数据库实例内存突然飙高,却无从下手排查原因?

2、如何降低数据库实例占用的内存?



心中有章,遇事不慌



作为DBA的你,遇到问题无从下手,除了在问题面前徘徊,还能如何选择?如果你一次或多次遇到该问题还是无法解决,又很懊恼,该如何排忧呢?关注公众号,关注《包拯断案》专栏,让小编为你排忧解难~


#包拯秘籍#

一整套故障排错及应对策略送给你,让你像包拯一样断案如神:


 #首先

遇到此类问题后,我们要做到心中有章(章程),遇事不慌。一定要冷静,仔细了解故障现象(与研发/用户仔细沟通其反馈的问题,了解故障现象、操作流程、数据库架构等信息


#其次

我们要根据故障现象进行初步分析。心中要想:是什么原因导致数据库内存被打满?例如:是出现了慢SQL,还是相关参数值设置有问题?


#然后

针对上述思考,我们需要逐步验证并排除,确定问题排查方向。


#接着

确定了问题方向,进行具体分析。通过现象得出部分结论,通过部分结论继续排查并论证。


#最后

针对问题有了具体分析后,再进行线下复现,最终梳理故障报告。



真刀实战,我们能赢



说了这么多理论,想必实战更让你心动。那我们就拿一个真实案例进行分析——某运营商业务系统部署运行了一套GreatDB分布式数据库,DBA突然接收到告警,某节点内存使用率99%,为了避免节点实例发生OOM,需优先解决数据库实力内存飙高问题,究竟是什么原因导致的呢?


01

故障发生场景

某运营商业务系统项目中,万里安全数据库GreatDB分布式集群计算节点发生监控告警,显示内存不足,内存使用率99%,DBA立刻登录系统处理内存飙高问题,并着手排查原因。


02

故障排查分析

free -h


top -c


select event_name,current_alloc from sys.memory_global_by_current_bytes limit 10;


show global status like '%Created_tmp%';


show variables where variable_name in('read_buffer_size','read_rnd_buffer_size','sort_buffer_size','join_buffer_size','binlog_cache_size','tmp_table_size');



# 查看performance_schema status

show engine performance_schema status;


检查慢SQL日志,分析后,发现不是慢SQL导致内存增高


# 查看是否使用jemalloc内存管理器

lsof -p 602275 | grep jem


# 收集pstack堆栈信息

pstack -p 602275


再分析堆栈日志内存,发现存在大量的 optimized out


03

问题定位:内存增高原因


  1. 因为数据库实例设置的innodb buffer pool为200G内存,实际使用了400G物理内存,设置innodb buffer pool过高,导致大量数据页缓存在内存中;


  2. 由于数据库实例使用了swap,swap大小为31G,数据库实例再使用内存时(比如:回放大事务、查询、事务中用到数据过滤、聚合等情况),发现可用内存不足时会进行swap的换入换出操作,导致内存波动较大;


  3. 分析performance_schema占用内存、session or global buff_pool 的内存占用和实际内存占用不符,经过pmap排查,发现存在大量匿名页;


  4. 通过pstack排查,发现大量线程处于(pthread_cond_wait@@GLIBC_2.3.2 () from lib64/libpthread.so.0 native_cond_wait(mutex=0x7f4a00351cb0, cond=)),此时确定了是剩余内存有匿名页的原因导致的。


04

解决措施


1.修改 innodb_buffer_pool 大小,由200G 到 150G

set global innodb_buffer_pool_size=150*1024*1024*1024;


2.使用gdb进行匿名页的回收

gdb --batch --pid 602275 --ex 'call malloc_trim(0)'


05

完成效果

swap内存使用由31G 降到10G,成功释放了20G内存;

匿名页释放:由452G 降到 264G ,释放了188G。



复盘总结



1.故障主要原因

设置innodb buffer pool过高,导致大量数据页缓存在内存中,存在大量匿名页,可用内存未及时释放出来。


2.优化建议

1)innodb_buffer_pool_size 设置不宜过高,应为系统内存的75%。当部署多个数据库实例在一台机器上,innodb_buffer_pool_size 按需分配即可;


2)禁用swap空间。



包拯断案 | 从库relay log损坏致主从同步报错 如何缉拿归案@还故障一个真相

包拯断案 | 当DDL与DML互相阻塞 如何缉拿归案@还故障一个真相

包拯断案 | MGR回放失败 该如何缉拿归案@还故障一个真相


关于万里数据库


北京万里开源软件有限公司(简称“万里数据库”)成立于2000年,是专注于国产自主可控数据库产品研发的国家高新技术企业、国家级专精特新“小巨人”企业,拥有发明专利、软件著作权百余项。


万里数据库的技术底蕴源自对底层核心代码的掌控,产品始终坚持以“极致稳定、极致性能、极致易用”为目标,经过20余年的研发经验积累,产品在功能、性能、稳定、易用等方面均处于行业领先水平,广泛应用于金融、运营商、能源、政府、交通等行业重要业务系统中的超2000个业务场景,得到了用户和市场的认可与肯定。


2021年,公司创立GreatSQL开源社区,通过对MySQL技术的优化,目前已成长为国内活跃的自主开源数据库社区


极致稳定  极致性能  极致易用



“在看”点一下,万里早知道


文章转载自万里数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论