干了十几年DBA,被问得最多的问题里,“数据库删了怎么恢复”绝对排前三。每次听到这个问题,我都能在电话那头听出绝望的语气——可能是手一抖点错了,可能是脚本写岔了,也可能是不小心覆盖了生产库。别慌,SQL Server不是那种删了就彻底没救的软件,但你得知道门道在哪。

先说最理想的情况:你做了完整备份。很多公司都有备份策略,但真到要恢复的时候,才发现备份文件放在同一块硬盘上,硬盘挂了,备份也一起没了。或者备份计划是配了,但从没验证过能不能恢复,真到用的时候才发现备份文件早就损坏了。所以第一件事,去翻你的备份历史,看最近的完整备份、差异备份、日志备份分别在什么时间点。如果备份文件还在,那恭喜你,直接用RESTORE命令就能拉回来,但这里有个坑——SQL Server的恢复是“链式”的,必须按顺序还原:完整备份→一个差异备份→之后所有的日志备份,中间缺一环,后面的全白搭。
要是没有备份呢?那就得看你是不是开了“简单恢复模式”还是“完整恢复模式”。简单模式下,SQL Server会自动截断事务日志,意味着你没法做时间点恢复,能找回多少全看运气。完整模式下,事务日志还在,理论上你可以把数据库恢复到删除前的那一刻。但这里有个前提:日志文件本身没被覆盖或截断。很多人不知道,删数据库的时候,如果用的是DROP DATABASE,SQL Server会直接丢弃数据文件和日志文件,这种情况下日志恢复基本没戏。但如果你是误删了表或者某个对象,那还有救——用第三方工具扫描事务日志,把那些DELETE、UPDATE操作挖出来,然后写反向脚本把数据插回去。
说到第三方工具,市面上确实有几款口碑不错的,比如Redgate的SQL Data Compare,ApexSQL的Log,还有Quest的Toad for SQL Server。这些工具的原理都类似:解析事务日志的LSN(日志序列号),把每一笔操作还原成可以执行的T-SQL脚本。但别指望它们能100%还原,尤其是遇到大事务、批量更新或者日志被循环覆盖的情况,能找回多少全看人品的。我见过最离谱的案例,客户用第三方工具扫了三天三夜,只捞回来一张只有三行数据的配置表,但就这三行数据,救了他们的生产系统。
再讲一个很多人不知道的冷门技巧:如果你的数据库还在,只是某个表被删了,而且你用的是SQL Server 2005以上版本,可以试试“系统表恢复法”——从系统表里把已删除的对象的定义和数据页找回来。具体做法是把数据库设为单用户模式,然后查询sys.sysschobjs这类系统表,找到被删除的对象的ID,再通过DBCC PAGE去读数据页。这个方法需要你有比较深的底层知识,而且操作不当容易把数据库搞得更乱,非专业人士不建议尝试。
还有一种情况,数据库文件还在,但服务挂了,或者服务器重启后数据库变成“可疑”状态。这时候别急着删文件重建,先把数据文件和日志文件的物理文件备份下来,然后尝试用DBCC CHECKDB修复。如果修复不了,可以试试CREATE DATABASE ... FOR ATTACHREBUILDLOG,让SQL Server重建日志文件。这个方法有时候能救回来,但数据可能是“脏”的,需要后续用逻辑判断来清洗。我遇到过好几个案例,客户以为数据库彻底废了,结果用这个方法把数据文件挂载回来,虽然日志丢了,但数据本身完整度在90%以上。
再强调一个极其重要的点:恢复数据库之前,先把当前的环境冻结住。什么意思?如果你要恢复一个生产库,但那个库还在被应用程序连接着,千万别直接还原,否则会报“数据库正在使用”的错误。正确做法是先把应用停掉,把数据库设为单用户模式,然后执行还原。另外,还原到不同的数据库名是个好习惯,比如把db_restore作为目标库,等确认数据没问题了,再改回正式库名。这样即使恢复出来的数据有问题,也不会影响线上业务。
我真心建议所有用SQL Server的团队,把“恢复演练”当成季度必修课。很多公司备份策略写得比上市公司财报还漂亮,但从来没真刀真枪地恢复过一次。等到真出事那天,才发现备份文件路径配错了、权限不够、磁盘空间不足,各种幺蛾子全都冒出来。恢复不是备份的逆操作那么简单,它需要你熟悉还原命令的每一个参数,知道WITH RECOVERY和WITH NORECOVERY的区别,理解STANDBY模式什么时候用。这些东西,不练永远不会。
回到标题那个问题:SQL Server删除的数据库怎么恢复?答案取决于你问的是“删了还没覆盖”还是“删了且跑了很久”。前者,备份+日志恢复+第三方工具,三管齐下,大概率能捞回来。后者,只能看运气了。但不管哪种情况,最值钱的不是那些命令和工具,而是你平时有没有做好备份、有没有验证过备份、有没有想过万一出事该怎么办。数据库这行,永远都是“防”大于“治”。下次再有人问你这个问题,你可以告诉他:先别急着哭,看看备份,再看看日志,实在不行,咱们再一起祈祷。


