我干这行十几年了,最怕半夜接到那种电话——电话那头声音发颤:“兄弟,数据库没了。”那种瞬间上头的感觉,就像你熬夜赶的方案,电脑突然蓝屏,所有改动全部消失。但说实话,数据库被删之后,慌是最没用的情绪。你越慌,手越抖,操作越容易出错,本来能救回来的数据,可能就因为一个多余的操作彻底没了。

数据库被删,分好几种情况。有的是误执行了DROP TABLE,有的是DELETE忘了加WHERE条件,还有更狠的——整个库被rm -rf了。不同情况,恢复的思路完全不一样。但不管哪种,第一条铁律就是:立刻停止写入。把数据库服务停了,把应用停了,甚至可以考虑把磁盘挂载成只读。为什么?因为新写入的数据会覆盖被删除数据所在的磁盘块。在数据库底层,删除操作很多时候只是标记了“这片空间可以用了”,物理数据还在,但一旦被覆盖,神仙也救不回来。
先说最常见的误删除表。如果你的数据库开启了binlog,并且binlogformat是ROW模式,那恭喜你,恢复概率很高。具体操作是这样的:先用mysqlbinlog工具把binlog解析成可读的SQL,然后找到误操作之前那个时间点,把那段SQL提取出来。比如你执行了DROP TABLE users,那你就找这个语句之前一个CREATE TABLE或者INSERT INTO users的binlog位置,然后执行mysqlbinlog --stop-position=那个位置,把数据导出成SQL文件,再导入回来。这个过程中最关键的,是要精确找到那个位置,差一行都不行。
如果你没开binlog,或者binlog被清除了,那就得靠备份了。那些说“我们从来不做备份”的团队,我见过太多。备份不是摆设,是救命稻草。全量备份加增量备份是最基本的配置。比如你用mysqldump每周做一次全量,每天做一次增量,恢复的时候先恢复全量,再恢复增量,加上binlog里的事务日志,基本能把数据恢复到故障前的一秒。但这里有个坑:备份文件本身也可能损坏。所以定期验证备份的可恢复性,比定期备份更重要。我见过有人备份了三年,从没恢复过,结果真出事那天,备份文件是坏的。
再说说物理层面的恢复。比如你用了rm -rf删除了数据库文件,或者不小心格式化了一个分区。这种情况下,千万别重启系统。重启可能导致文件系统的元数据被重新写入,本来能恢复的文件就彻底没了。正确的做法是:立即umount那个分区,然后用数据恢复工具去扫描。Linux下可以用extundelete或者testdisk这类工具。extundelete主要针对ext3/ext4文件系统,用法很简单:先卸载分区,然后执行extundelete /dev/sdb1 --restore-all,它会尝试恢复被删除的inode指向的数据块。但注意,这个工具不是万能的,如果文件被覆盖了一部分,恢复出来的文件可能不完整。
还有一种情况更隐蔽——事务日志损坏。比如MySQL的iblogfile文件坏了,或者PostgreSQL的WAL日志出了问题。这时候数据库可能直接启动不了,报错说“corrupted”。很多人第一反应是重建日志文件,但这是最危险的操作。因为事务日志里可能还有未提交的事务,重建日志意味着丢失这些事务的数据。正确的做法是:先用InnoDB的forcerecovery参数,从1开始逐步增加尝试启动。比如在配置文件里加上innodbforcerecovery=1,然后尝试启动数据库。如果不行,改成2、3、4……一直到6。每增加一级,数据库会跳过一些检查,启动成功的概率越大,但数据完整性损失也越大。启动成功后,赶紧把数据导出来,重建一个干净的实例再导入回去。
云数据库的情况又不一样。很多公司把数据库放在RDS、阿里云RDS或者腾讯云上,这些平台一般都有自动备份和回收站功能。比如阿里云RDS支持按时间点恢复,可以恢复到7天内任意一秒。但有个前提:你得确认你的实例开启了自动备份。我见过有人用免费版RDS,默认备份保留7天,结果误操作发生在第8天,备份已经过期了。所以如果你用云数据库,赶紧去控制台看看备份策略,把保留天数设长一点,同时开启日志备份。另外,云数据库的“回收站”功能也很有用,比如腾讯云的CDB支持回收站保留7天,误删的实例可以在这里找回。
说个容易被忽略的点:操作记录。很多人恢复数据时,完全记不清自己什么时候执行的删除命令。如果你用的是MySQL,可以在数据库里创建一个auditlog表,用触发器记录所有DDL和DML操作。或者直接用MySQL的auditlog插件。这样即使没有binlog,你也能知道精确的删除时间,然后根据这个时间去恢复备份。PostgreSQL也一样,可以用pgaudit插件。这些配置虽然增加了一点性能开销,但比起数据丢失的代价,这点开销不值一提。
说到底,数据恢复这件事,七分靠预防,三分靠技术。预防做得好,恢复就是走个流程;预防做得差,恢复就是跟时间赛跑。该开的备份开了没?该设的保留周期设了没?该做的恢复演练做了没?这三个问题,你今晚就去检查一遍。别等到电话响了才想起来,那时候再手把手教,也救不了你的黑眼圈。


