今天发一篇与以往不一样的内容,这是一篇来自生产实践的记录。我只是作了一下编辑和修订的工做。python
刘老师经过记录真实的案例的形式,对故障排除的过程进行总结和反思。文中不但描述了刘老师解决问题的思路,还清晰的记载了解决问题的方法。仔细阅读此文,你会发现刘老师对故障的排除和修复有着清晰的思路和严谨的执行方法。另外,经过此文,还能够发现刘老师的一大爱好,去GitHub查找资源,并加以利用。这一举动不但体现了开源软件的优点,也体现了开源爱好者的理念。接下来,让咱们阅读刘老师的原文。mysql
做者:刘宝珍 git
岗位:架构师,目前就任于大型资产管理公司的科技子公司,拥有多年的大型私有云的规划和设计工做经验,熟悉软件的开发流程,目前醉心于研究基于DDD和敏捷的软件的开发模式,对分布式架构有深刻的理解,同时也但愿同各位朋友交流软件架构和云计算架构的经验,在此也感谢徐老师对于本文的审核和修订。github
2020年2月25日,微信的朋友圈大量转载微盟遭遇了系统重大故障,36小时内还没有恢复核心生产数据,从而想到本人在两周前处理的一个案例,开发人员误删除了生产数据,本人恢复的一个过程,同时给这个故障的处理过程作一个总结,也对学过的知识作一个梳理,但愿对运维的同窗们有一个警示做用。sql
2.13日23:00接到微信通知,可否帮忙恢复数据。数据库
系统环境信息以下:服务器
操做系统:RHEL7.5微信
工做流平台:开源activity架构
业务应用:调用activity,生成该应用的流程数据。运维
工做流使用的数据库:MYSQL 5.7 社区版,一主两备。
23:05,开始介入数据丢失的故障。
确认一个大概解决问题的思路:
1. 找到是什么人在什么时间点作了什么操做? 2. 这个操做对系统的影响有多大,是否对其余系统有影响?确认这个操做是否是正常业务体现? 3. 确认数据库里受到影响的日志的时间段。 4. 在仿真环境复盘整个故障。 5. 制定技术恢复方案,在仿真环境验证数据恢复方案。 6. 在仿真环境验证数据恢复后应用是否正常。 7. 备份生产环境数据,应用数据恢复方案到生产环境。 8. 生产环境绿灯测试,无误后,恢复完成。
因为恢复生产数据是重大的数据调整,须要报请领导批准,须要有完备的数据回退方案。
用了5分钟理清了处理这个问题思路,接下来就是考虑具体的数据恢复了。在处理这个问题过程当中,有两个难点须要解决。
确认要恢复的binlog的开始和结束。
首先解决第一个问题:
询问开发人员,开发人员给出晚间大概20:20左右操做rest接口,调用了activity(如下简称工做流)平台删除流程模板的操做,致使该流程模板下全部的流程实例所有被删除,在该流程模板下有5个在途的流程还没有处理完成。
根据开发人员的描述,登陆到工做流平台的数据库,查看数据库在20:20左右的binlog 文件,并对11号binlog文件进行备份。
将binlog拷贝到一个开发的服务器,经过mysqlbinlog进行解析。解析命令为:mysqlbinlog -v --base64-output=decode-rows --skip-gtids=true --start-datetime='2020-02-13 20:10:00' --stop-datetime='2020-02-13 21:30:00' -d {$DBNAME} mysql-bin.000011 >>aa.log dbname作了脱敏处理。
观察解析后的sql,在20:20分并未发现大量的删除操做,确认开发人员的话不可信,作故障诊断的第一原则:任何人的话都不能全信,也不可能不信,带着疑问来找到论据证实他的说法。
继续翻看解析的binlog,20:30开始出现大量的delete和update等操做,开始怀疑这一点是否是有问题的时间段。
将这一段的sql进行概括总结,概括须要操做几个表,对这个几个表的操做类型,以及操做的数据的类别(业务ID)。同工做流平台的同事进行确认,删除一个工做流的模板,是否是涉及到这些表的变动,工做流平台的同事确认是这个过程,数据恢复的但愿诞生了!
根据之前的经验积累,github上有个开源项目binlog2sql,能够将binlog的event翻译成sql语句,也能够翻译成反向sql,顿时以为这个问题应该很“容易”解决了。
根据以上思考,开始在仿真环境里安装binlog2sql工具,该工具就是一个python的程序,须要安装好python环境以及须要的三方库便可,具体的使用方式请参考:https://github.com/danfengcao/binlog2sql,同时也再次感谢工具的做者曹老师。
以上几个过程,已经解决了第一个问题,接下来咱们要解决第二个问题。
在以上的步骤里,已经在仿真环境复盘了生产环境的故障,同时在也仿真环境里里安装了binlog转成sql的工具。
使用binlog2sql的工具,解析出来错误执行的sql,让工做流的平台的同时进行确认,同时让工做流的同事,确认在这个时间段内没有其余的应用也在操做这个数据库。
(a) 在仿真环境模拟建立一个工做流模板。
(b) 在这个模板上建立几个测试实例
(c) 经过接口去删除这个工做流模板,观察应用产生的sql,以此来确认本人提供的sql是否正确。
同时,工做流平台确认在问题时间段内无其余应用操做,感受胜利在望了,该问题能够轻松解决了。
表中有个字段为longblob字段,产生的insert的sql没法执行,这个问题该怎么处理?
这个问题到这里陷入了僵局,眼看立刻就能解决的问题,发现有一个表数据没法经过sql进行插入,询问工做流平台同事,这个表是否很重要,获得答复,没有这个表的数据,系统没法运转。
换个思路考虑一下,既然sql是经过二进制的binlog生成的,能够考虑生成反向的二进制binlog,而后把这一段反向的binlog应用到数据库,这个问题就解决了。
带着这个思路,去github里翻看了项目。果真还真有一个:https://github.com/Meituan-Dianping/MyFlash 再次很是感谢美团点评开源的myflash项目。
经过以上分析,基本上就能够轻松解决这个问题。对本身提出几个问题:
在这个系统上,数据已经备份了,天天都有全备,不能使用这个恢复的缘由,工做流平台里有不少应用的流程引擎,一旦作了基于时间点恢复,别的应用的系统数据一块被恢复了,将会致使别的系统会丢失一部分数据。
由于工做流平台是一个开源的平台,数据模型之间的关联性特别强,若是基于表的恢复,容易致使数据的约束出现问题。
反思:
开发人员在生产上线过程越过了仿真环境,直接上生产,对生产上线过程并不严谨,虽然有管理流程,可是对流程的过程执行不力。
结合以上分析过程,须要指定一些辅助策略来完善发布流程。
发布流程自动化,应用代码发布自动化发布,尽可能避免人为参与。
全文至此结束。