《MySQL——从删库到跑路》阿里架构师分享删库跑路救命策略
首先看下 mysql 误删数据排名最前的几种是:
误删文件
误删库、表
错误全表删除 / 更新
升级操作失误
都来看看你命中过几个,hoho。
简单说下我亲手造的一个大事故吧。
那大概是一个春暖花开的季节,我的内心是激动澎湃的,因为已经安排了休假计划。在这前几天,已经把一个新项目的数据库环境都部署好了,包括自动化备份。
等我美美的出去玩的时候,悲剧发生了,业务要求进行数据回滚,但发现备份文件不可用,原因是备份时指定的字符集和表字符集不一致。我勒个擦,原来该项目采用新的字符集,但是我没有认真检查确认并修改备份脚本,结果导致备份失效。最后,因为这个事,当季度绩效结果被降档,boss 也为此背锅~
好吧,回到正题,先说几点我平时预防误操作导致文件/数据丢失不成熟的建议:
欲删除文件时,将 rm 命令改成 mv,可在系统层面将 rm 命令做个 alias(或参考 Windows / Mac OSX 做法,删除文件时先进回收站)。
删除数据库、表时,不要用 drop 命令,而是 rename 到一个专用归档库里;
删除表中数据时,不要直接用 delete 或 truncate 命令,尤其是 truncate 命令,目前不支持事务,无法回滚。
用 delete 命令删除数据时,应当先显式开启事务,这样误操作时,还有机会进行回滚。
要大批量删除数据时,可以将这些数据 insert…select 到一个新表,确认无误后再删除。或者反其道行之,把要保留的数据写到新表,然后将表重命名对掉。
执行重要命令之前,先准备好相关命令,再三确认无误才之行,对于新鸟而言,最好请你的 boss 坐你旁边镇场几次,否则极有可能会连累大家~
以上几条,也是我自己奉行的原则。总之,要时刻保持对线上生产环境的敬畏之心。虽说现在大部分操作可以靠平台来完成了,但平台也不是万能的,不也发生过平台本身的缺陷造成数据丢失、代码回滚、部署失误等事故嘛,我就不点名了。
做好备份,不管是物理备份还是逻辑备份!做好备份,不管是物理备份还是逻辑备份!做好备份,不管是物理备份还是逻辑备份!
重要的事情说三遍都不嫌多。
说完预防措施,我们再说万一发生误操作时,怎么以最快速度进行补救。 我们分别列举几种常见的情况:
执行 DROP DATABASE / DROP TABLE 命令误删库表,如果碰巧采用共享表空间模式的话,还有恢复的机会。如果没有,请直接从备份文件恢复吧。神马,你连备份文件都没有?那麻烦退出 DBA 届吧,一个连备份都懒得做的人,不配成为 DBA 的。
接上,采用共享表空间模式下,误删后立刻杀掉(kill -9)mysql 相关进程(mysqld_safe、mysqld),然后尝试从 ibdataX 文件中恢复数据。
误删除正在运行中的 MySQL 表 ibd 或 ibdataX 文件。请立即申请对该实例进行维护,当然,不是指把实例关闭,而是把业务暂停,或者把该实例从线上环境摘除,不再写入新数据,然后利用 linux 系统的 proc 文件特点,把该 ibd 文件从内存中拷出来,再进行恢复,因为此时 mysqld 实例在内存中是保持打开该文件的,切记这时不要把 mysqld 实例关闭了。
接上,把复制出来的 ibdataX 或 ibd 文件拷贝回 datadir 后,重启 mysqld 进入 recovery 模式,innodb_force_recovery 选项从 0 – 6 逐级测试,直至能备份出(整个实例或单表的)所有数据后,再重建实例(或单表),恢复数据。
未开启事务模式下,执行 delete 误删数据。意识到后立即将 mysqld(以及 mysqld_safe)进程杀掉(kill -9),不要任何犹豫,然后再用工具将表空间数据读取出来。因为执行 delete 删除后,实际数据并没被物理清除,只是先打上 deleted-mark 标签,后续再统一清理,因此还有时间差。
执行 truncate 误清整表。如果没使用共享表空间模式的话,基本别想了,走备份恢复+binlog 吧。
执行不带 where 条件的 update,或者 update 错数据。也别费劲了,走备份恢复+binlog 吧
评论