一条 delete 忘了写 where,或者 drop 点错了库——手滑的那一秒,接下来几分钟你做什么,直接决定了数据能不能回来。绝大多数救不回来的案例,都不是技术不行,而是第一反应做错了:有人马上重启数据库,有人急着重新部署,有人往同一块盘里拷恢复工具。这篇文章不讲备份怎么做,只讲误删、误改、覆盖发生之后的那几分钟,顺序应该怎么走。
一、第一件事:立刻停手,让写入停下来
误删之后,数据在物理介质上通常还没有被真正抹掉,数据库的操作日志多半也还记着过程。但只要有新的写入进来,这些空间就可能被覆盖,或者日志被轮转掉。所以第一动作是把写入停掉:应用切维护模式,数据库设成只读,定时任务也一起停。别再让业务往里写,也别让任何人“顺手帮你补一下数据”。
这一步要快,但不需要慌到把数据库进程直接强杀。稳妥的做法是让应用先断开连接、再设只读,优雅地停下来。强杀有可能让还没落盘的数据也跟着出问题,把一件麻烦变成两件。
二、第二步:判断是哪一种误操作
不同的误操作,救法完全不同。删了一行或一批记录,靠增量日志基本能反推出来;drop 掉一整张表,要走“备份加重放”这条路重建;update 忘了条件、把一列全改错了,得先确认改之前的值还有没有别处留着——从库、快照、导出文件都算;文件被覆盖或删除,走的又是文件系统那条线。先把类型判清楚,再决定手段,别上来就一个个试。
三、这四件事千万不要做
不要重启数据库。重启会滚动日志、清掉缓存,把一些本来还能利用的现场弄没了。
不要往同一块盘写东西。你下载恢复工具的每一个字节,都可能正好盖在你要找的数据上面,这个代价是不可逆的。工具装到别的盘,或者干脆拿到别的机器上跑。
不要急着重装或者重新部署。重装解决的是环境的问题,而你现在要找的是数据,两者没有关系,重装之后只会让你更难判断原来那台机器上还剩什么。
不要拿生产库当试验场。所有恢复动作先在隔离环境里跑通,确认结果对了再上生产。
四、能救回来的几条路,按优先级排
排在第一的是从库或者快照。如果有一台延迟同步的从库,误操作还没传过去,那就是最干净的恢复源,直接切过去最快。第二是增量日志。只要误操作之后还有正常写入,就不能简单地把全量备份恢复回来,那会把后续数据一起丢掉,正确做法是恢复全量、重放日志,并且把误操作那一段跳过去。第三是云平台的快照或者磁盘快照,粒度粗但可靠。第四才是文件恢复工具,成功率取决于你停写停得够不够快。
动手恢复之前,先用下面这几条命令确认增量日志开着、当前写到哪个文件,再把误操作的位置找出来。
# 1) 先确认增量日志开着,以及当前写到哪个文件
mysql -uroot -p -e "show binary logs;"
mysql -uroot -p -e "show master status;"
# 2) 把日志转成可读文本,找出误操作语句出现的位置
mysqlbinlog --base64-output=DECODE-ROWS -v /var/lib/mysql/mysql-bin.000123 > all.sql
grep -n -i "drop table\|delete from\|truncate" all.sql | tail -30
# 3) 恢复到误操作之前的位置,位置比时间更准
mysqlbinlog --stop-position=158426 /var/lib/mysql/mysql-bin.000123 | mysql -uroot -p shop
# 4) 误操作之后还有正常写入,就跳过那一段接着往后重放
mysqlbinlog --start-position=158930 /var/lib/mysql/mysql-bin.000123 | mysql -uroot -p shop
第 2 步打印出来的行号是定位误操作的坐标,前后各留一点余量,把位置卡在语句开始之前。第 4 步是这套流程里最容易出错的地方:跳过的那一段要刚好包住误操作,跳多了会丢正常数据,跳少了等于没跳,所以前后的位置都要先在隔离环境里试一次再上生产。
五、文件被误删或覆盖怎么办
文件层面的抢救逻辑和数据库不一样。先把那块盘或者那个目录所在的挂载点变成只读,条件允许就把盘卸载下来,彻底断掉写入;然后按文件系统类型用对应的恢复工具扫描;如果目录是被整个删掉的,别在原盘上做任何解压、下载、安装动作,工具装到别的机器上再扫。整个过程里,决定成败的只有一件事:停得够不够快。
六、恢复完一定要验
恢复出来的数据要抽查,重点核误操作前后那段时间的记录:边界上那几条在不在、总数对不对、关联关系有没有断。数据库层面再看一遍表的行数和关键字段的空值情况,跑通一遍业务流程,确认应用读到的数据是正常的。恢复了数据却把应用弄挂,等于没恢复。
七、真正省事的做法是提前防
几种花小成本防大事故的做法:开一台延迟从库,同步延迟设成半小时到几小时,误操作就有了一个缓冲窗口;把增量日志的保留时间设得比全量备份间隔更长;把生产账号的权限收紧,drop 和 delete 这类权限不要给业务账号;执行删除和更新之前,先把要跑的语句放到预发环境走一遍。这些事平时看不出价值,出事那天每一条都能救你一次。
手滑谁都免不了,区别在于有人手滑之后数据没了,有人手滑之后一小时恢复上线。中间隔着一套提前做好的机制,加上出事那几分钟里克制住的那双手。
相关阅读:
A5创业网 版权所有