#dbaplus社群#十年难得一遇!从数据误删到全量恢复的惊险记录


作者介绍
贝壳找房DBA团队 , 负责支撑起贝壳找房平台的数据库运维及数据库产品的开发工作 , 努力提供高效、稳定、安全的数据库服务 。
引言
线上的数据库服务我们有完善的备份策略和恢复预案 , 数据即使被误删除了也是能够恢复的 , 误删除的数据量恢复只是时间问题 。 但各位同学自己部署的测试环境或者是在自己电脑中的开发环境的数据库就没有同级别的资源保障了 。 如果恰好你又把一些不能丢失的数据放到了这种环境中 , 那么建议要做定期备份 , 有备才能无患 。
今天给大家分享的案例便是这种在线下自搭建环境的一次数据误删除事件 。 数据不幸被删除和万幸能被全量恢复可谓十年一遇 。
事件背景
测试环境中的一台服务器准备做迁移替换 , 小 A 同学接到了这个光(危)荣(险)的任务 。 小 A 选择了直接 rm -rf /mysql 删除这台机器上挂载的数据分区来清理磁盘空间 。
不到两分钟 , 还在挑灯夜战的某位同学就发现一个常用的测试环境无法正常使用了 。 这时候的小 A 定是心如止(死)水(灰) , 还是找 DBA 帮忙看看吧 。
值班 DBA 小 D 被电话叫起紧急支援 , 但小 D 登录到服务器上一看也淡(傻)定(眼)了 , 数据、日志、软件环境统统都被删除了 , 唯一的一次备份是一年前升级测试环境数据库时做的备份 。 给 DBA 老 A 打电话吧 , 问问他的建议 。
#dbaplus社群#十年难得一遇!从数据误删到全量恢复的惊险记录
本文插图
恢复经历
一旦发生了误删数据先不要慌 , 停止所有操作 , 第一时间寻求帮助 。 即使您是老司机 , 这时候也要找一位同学帮忙一起观察后续的操作 , 避免手抖出现再次误操作 。
另外要强调的是 , 在出现数据误删除的服务器上同时只能有一个人操作 , 其他人应通过桌面共享软件或站在操作人身后观察 , 避免多人交叉操作出现二次故障 。
1、找回数据文件
老 A 在得知数据、日志和软件环境都被删除后 , 先使用了 ps 命令查看 mysqld 进程是否还存活 。
进程还在 , 这就有戏了 , 不幸中的万幸 。 抓紧到 /proc/${pid}/fd 目录看看有没有还未关闭的表可以抢救 。
#dbaplus社群#十年难得一遇!从数据误删到全量恢复的惊险记录
本文插图
真是太幸运了 , 这个测试环境里面的表比较少 , 所有表的数据文件还都是打开状态 。 数据被找回的概率就很大了 。 接下来就是如何把这些显示为 deleted 的文件从文件系统中找回了 。
在介绍如何找回被删除的文件前 , 先来介绍一个运维经常会遇到的删除了文件 , 但磁盘空间不释放的问题 。 下图是一个模拟的例子 , 当 test.txt 文件被 tail -f 命令使用时 , rm test.txt 并不会释放空间 , 当将 tail -f 命令 ctrl+c 中止后 , 磁盘空间才释放 。
#dbaplus社群#十年难得一遇!从数据误删到全量恢复的惊险记录
本文插图
一个文件在文件系统中的存放分为两个部分:数据部分和指针部分 , 指针位于文件系统的 meta-data 中 , 数据被删除后 , 这个指针就从 meta-data 中清除了 , 而数据部分存储在磁盘中 , 数据对应的指针从 meta-data 中清除后 , 文件数据部分占用的空间就可以被覆盖并写入新的内容 , 之所以出现删除 test.txt 文件后 , 空间还没释放 , 就是因为 tail -f 进程还在一直打开这个文件句柄 , 文件对应的指针部分由于进程锁定 , 并未从 meta-data 中清除 。 由于指针并未被删除 , 那么系统内核就认为文件并未被删除 , 因此通过 df 命令查询空间并未释放 。
有了之前遇到的类似经验我们知道 , MySQL 被删除的数据由于句柄还在打开状态 , 因此还未完成删除 , 是可以被找回的 , 已经关闭的表就无法找回了 。 找回的方法也比较简单 , 直接 cat 对应的文件句柄 , 再通过管道(pipe)或输出重定向的方式即可找回原来的数据文件了 。 但要注意的是为了保证原来的磁盘不要再被写入新的数据 , 不要在原分区下做磁盘写操作 。 这次的环境是部署在云服务器上的 , 再挂载一块新的云盘到这台服务器上就能把数据文件找回了 , 找回方式如下图所示: