干这行的人心里都清楚,数据库还原这事儿,平时用不上几回,可真到了要用的时候,往往都是火烧眉毛的节骨眼。要么是硬盘突然罢工,要么是误删了整张表,再要么就是机房断电导致数据库文件损坏。你翻遍整个办公室,发现没人能拍着胸脯说“我熟”,因为大家平时都在忙业务优化和查询调优,谁没事天天练还原啊。可SQL Server 2008这个版本,如今还在生产环境里跑着的企业不在少数,它不像2012、2016那样自带一堆花哨的恢复功能,很多坑得你亲自踩过才知道。

先说最简单的场景:你手里有一份完整的.bak备份文件,服务器上实例也活着,还原命令就三行。RESTORE DATABASE 库名 FROM DISK = '路径' WITH REPLACE,这句是核心,REPLACE的意思是允许覆盖现有数据库,不加它,如果目标库已经存在,系统会直接报错。然后你可能会遇到一个特别常见的报错——"数据库正在使用,无法获得独占访问权"。这多半是因为有别的连接正挂在那,哪怕是个闲置的查询窗口,也会挡你的路。解决办法也粗暴:先执行ALTER DATABASE 库名 SET OFFLINE,或者直接把所有相关连接杀掉,用sp_who2查一下进程ID,KILL掉就行。
但比这更麻烦的是,你拿到的备份文件可能是从另一台服务器上拷过来的,数据库逻辑文件名和物理路径对不上。比如原服务器上数据文件在D盘,你这边只有C盘,或者目录结构完全不同。这时候直接还原,系统会按照备份文件里记录的路径去找,找不到就报错。你得在RESTORE语句里加上WITH MOVE选项,把逻辑文件名映射到你本地的物理路径。先查逻辑文件名,用RESTORE FILELISTONLY FROM DISK = '路径',它会列出这个备份里包含了哪些数据文件和日志文件,以及它们的逻辑名称。然后照着这个列表,一条条MOVE过去,这事才算完。
还有一类情况,是你手头只有日志备份,没有完整备份。比如某天上午你做了完整备份,下午误删了数据,想恢复到删除之前的状态。这时候你得先还原中午的完整备份,而且要用WITH NORECOVERY选项,让数据库保持“正在还原”状态,不能接受用户访问。然后紧接着还原下午的日志备份,也是WITH NORECOVERY,再执行RESTORE DATABASE 库名 WITH RECOVERY,把数据库带回到可用状态。这套动作下来,数据就能恢复到日志备份的那个时间点。但有个前提,你得保证日志链没断过,中间如果做过收缩或者切换了恢复模式,这招就不灵了。
说到恢复模式,很多人在这里栽过跟头。SQL Server 2008默认是简单恢复模式,这种模式下日志备份根本不存在,你只能做完整备份和差异备份,而且还原到某个时间点是想都别想。如果你有那个需求,必须在建库的时候就改成完整恢复模式,或者至少在你打算做时间点恢复之前,先改过来,然后做一次完整备份,让日志链的起点生效。很多运维老手会强调,生产库一律用完整恢复模式,哪怕你嫌日志文件涨得快,也得定期备份日志、截断日志,而不是图省事切到简单模式。因为一旦切换,日志链就断了,之前所有日志备份全部作废。
再讲一个容易被忽略的细节:备份文件本身可能已经损坏。你从网盘下载,或者U盘拷来拷去,哪怕一个字节出错,还原的时候就会报“备份集有效,但无法应用”之类的错。SQL Server 2008的备份文件没有内建校验机制,你得自己确认文件完整性。做法是用RESTORE VERIFYONLY FROM DISK = '路径',这命令会检查备份集是否可读,文件是否完整。但它也只是粗略检查,不能保证100%能还原成功。真正靠谱的办法是定期做还原演练,别等到灾难发生才想起来试。有些公司规定每个月必须把备份文件还原到一台测试机上,跑几个业务查询验证一下,这习惯救了不少人。
还有种情况是,你要还原的库比原来小,磁盘空间不够。SQL Server 2008还原时不会自动压缩文件大小,它严格按照备份文件里记录的文件大小来分配空间。你原库数据文件有200GB,现在目标盘只剩150GB,那还原必定失败。要么你提前清理磁盘,要么用WITH MOVE把文件挪到别的盘上,要么就得接受现实——这库本来就该扩容了。另外,还原过程中如果中途断了,比如网络抖动或者硬盘写入错误,SQL Server会留下一个“未完成”状态的数据库,这时候你再想还原就得先把那个残留库删掉,否则会一直提示“数据库正在使用”。
想说,还原这东西,宁可备而不用,不可用而不备。SQL Server 2008已经停止主流支持了,很多安全补丁和功能更新都没了,但存量系统还在跑,所以掌握还原技术就显得更重要。建议你找个空闲时间,拿一台虚拟机,把备份、还原、日志备份、时间点恢复这些流程全部走一遍,把踩过的坑记下来。真到了需要出手的时刻,你会发现,那些平时看着枯燥的命令行,就是你最可靠的救命稻草。数据库还原不是炫技,是给自己留后路。


