MySQL 的数据去哪了

来源:互联网 发布:黄金外汇软件 编辑:程序博客网 时间:2024/05/29 13:20

周四早上,刚到单位。

 

同事A:  很着急的说,你们昨晚干什么了,预生产环境中MySQL中的数据丢了?


我:   登录数据库一查,他说的那张表果然没有数据。问到,什么时候发现数据丢失的?


同事C:昨天晚上8点左右,他们的程序更新了,重启后就发现数据丢了。昨天下午还用的 好好的。

 

领导A:  XX  怎么回事,数据为什么会没了,快查一下。

领导B:  怎么样了,查到原因没有?

领导C: 我等着用呢,没有数据我什么也干不了。

 

同事D, E,F,G,H,I,G,K,L,M ......X,Y,Z 纷纷过来围观,可能是想帮我分析和解决问题吧。 其实他们不但没帮到我,反倒给我添了不少的压力。

 

从反映的情况来看,是数据被删除了,是谁干的呢,要找出问题的原因,还真不那么容易。

 

 1. 首先有权限登录数据库的人有限,只有两个DBA,和一个Team Leader。DBA 不会没事去删预生产的数据,给自己找麻烦。那个Team Leader 主要负责日常工作的管理,很少会登录数据库。

 

 2. 应用方面的帐号权限有限,只能delete,不能drop,truncate。现在那张表升级前的数据被清空了,应该不是从业务端drop ,或truncate 掉了。还有一种可能就是delete 没有where条件。不过上预生产的程序都是经过测试的,应该不会出这么低级的问题。

 

3. 检查了MySQL的主机登录记录和执行的历史命令,均未发现异常。

 

4. 看来只能分析MySQL的BINLOG了。找到昨天的BINLOG,分析并未发现有对这个表的CREATE,DRO,UPDATE,DELETE,TRUNCATE,ALTER操作。由于用了一致性HASH算法做分库分表,这张表的数据是分布在4个MySQL 实例上的。因此要到4个实例上分别检查BINLOG。

 从分析MySQLBinlog的结果发现,从那天凌晨到升级前居然没有对那个表的insert和update操作。只是在升级后开始有insert操作。

 

5.此时又不停的有同事和领导过来询问事情的进展情况,对他们的答复只能是还没分析到原因。

 

此时该怎么办呢?

 

疑点一:会不会是有人故意在清空表数据的时候,在会话级别设置了不写binlog呢,但我很快排除了这个想法,因为知道这个方法的人真的不是很多,况且谁也不会没事跟我过不去啊。

 

既然昨天的Binlog里没有发现异常,那就继续往前面的备份和binlog里找吧。结果发现这个表在周一是有数据的,但在周二的晚上升级演练的时候做过数据清理。但从那以后到周三晚上的程序升级前,都没有数据的写入。目前从binlog的分析情况,就是这样。

 

但他们一直咬定周四下午升级前还能看到历史数据,这是为什么呢?

 

疑点二:程序在周四前访问的不是预生产库,经确认后否定了这个想法。

 

疑点三:我分析binlog的方法有问题,可能忽略了某些细节,导致未发现问题。于是请我们的另一位DBA一起分析binglog,结果我们的分析的结果是一致的。

      

    实在是想不到问题的原因了 ,那就让问题飞一会吧,先吃午饭在说。这是我一贯的原则,吃饱了才有精力干活。或许休息一下,换个思路问题就解决了。

 

下午又是那个同事过来,从应用过来的数据都插不到库里。但是直接从mysql的客户端,运行相同的语句却能插进去,问这是为什么?

 

亲,看到这,你能猜出问题的原因了吗?

 

CASHE ,对了就是它。 当A接口调用B接口向数据库里写数据的时候,B接口先判断自己的缓存里有没有数据,如果有是不会插入的,没有才插入。

从B接口的日志中看到,之所以A接口传过来的请求没有被写到数据库里,是因为B接口的缓存里有数据,所以A接口发过来的数据没有被查到库里。

但这个跟数据丢失有什么关系呢?

 

原来在升级演练时,虽然清空了数据库里的数据,但B接口的缓存里还有数据,并且在数据库里的数据被清空后,B接口没有重启,所以导致他们读到的都是缓存里的数据。这是他们程序的一个BUG.

 

     至此问题的真相终于浮出了水面,我也可以喘口气了。正好敢上公司的大BOSS来验收,如果找不到问题的根源,后果可想而知。于是我赶紧把问题经过总结成文档。刚刚写完,跟大BOSS开会的一个同事就过来问我,找到问题的原因了吗?我很快的跟他说明了问题的来龙去脉。

 

现在回想,那天的工作情况跟当天的股市走势非常相似,乘V字形,开始一落千涨,好歹又涨了回来。

 

有时候头痛真的不能只医头,真有可能是其它地方的问题。

0 0