作者 姜宇祥,曾就职于达梦和携程,目前在CDB/CynosDB数据库内核团队担任TXSQL云数据库内核研发,多年深耕数据库领域,为国内早期一批数据库内核研发人员。过去曾在达梦经历了新一代达梦从零开始的整个研发过程,并参与多个版本的迭代与架构调整;还曾在携程率先开启MySQL的定制开发,为线上业务提供支持。另一方面,他也积极参与MySQL开源社区在中国成长过程,通过技术宣讲与文章编写助力MySQL在中国的传播。
引言
在数字领域,TX王国是一个统御着“成T上P”数据子民的大国,这里的T和P是极大极大的数,用成千上万来形容数据量之多并不为过。X侦探事务所就是TX王国中负责MySQL领域管理数据子民的有关部门,而事务所中探员们就是专门负责解决各种各样突发事件的战斗精英。
我们将要讲述的是关于这些探员的侦探故事,他们擅长在海量的数据中追寻蛛丝马迹,屡破奇案。这次,我们将要讲述的是一个连环宕机血案的侦破故事。
案发现场
一天,探员T因遇到了一个棘手的MySQL实例宕机问题而头疼不已,通过内部的监控系统发现一个MySQL数据服务使用的内存就像坐了加了速的小汽车一样飞速上涨。操作系统为了保证整个系统的运行,不得不将该MySQL服务杀死,以释放足够的资源用于系统正常运转。这是一个很严重的问题,任何服务的宕机以及内存不正常现象都是要优先进行排查并处理。
内存溢出(Out Of Memory)
一般是由于程序编写者对内存使用不当,如没有及时释放申请的内存资源,导致该内存一直不能被再次使用而使计算机内存被耗尽的现象。杀死进程或重启计算机可从操作系统层面解决问题,但根本解决办法还是对代码进行改进。
案件经过
面对这种紧急情况,经验丰富的探员T迅速登录服务器查看情况。首先怀疑的是打开的表太多,导致大量的表对象占用了内存空间。经过对frm文件和ibd文件的底层粗略查询,该MySQL实例上有20多万张的表。那么,大量的表对象占用了内存空间的必要条件就成立了。于是进一步查看,限制表打开数目的变量“table_definition_cache”是否设置的过大,导致占用的内存过多。
但是,该变量并未如预期中设置的过大,属于合理范围。那么为什么内存还会占用如此之多?探员T此刻陷入了深深的思考。现在案件似乎走入了一个死胡同,也就是存在大量的表但是对打开表的资源限制在了一个合理的范围内,这似乎是一个悖论。关键问题来了,到底是哪里占用了大量的资源呢?