您现在的位置是:烟消火灭网 > 百科
sql恢复备份数据库
烟消火灭网2026-10-17 07:46:49【百科】7人已围观
简介凌晨三点,电话响了。客户那边一台跑了三年的订单系统,硬盘直接挂了。备份文件倒是有,一个 28GB 的 .bak,躺在网络存储上。问题是他从来没真正恢复过——建库的时候顺手点了个“备份”,之后就没管过。
凌晨三点,复备份数电话响了。据库客户那边一台跑了三年的复备份数订单系统,硬盘直接挂了。据库备份文件倒是复备份数有,一个 28GB 的据库 .bak,躺在网络存储上。复备份数问题是据库他从来没真正恢复过——建库的时候顺手点了个“备份”,之后就没管过。复备份数我远程连上去,据库打开 SSMS,复备份数右键“还原数据库”,据库选文件,复备份数点确定。据库进度条卡在 40% 不动了。复备份数弹窗:System.Data.SqlClient.SqlError: 媒体集有 2 个媒体簇,但只提供了 1 个。
这行报错的意思是:你当初备份的时候,数据被切成了多个文件,现在你只拿了一个过来。很多人不知道,SQL Server 备份默认可以写成多个 .bak 分片,尤其在大库上,DBA 为了跑得快会拆成几个文件并行写。你只恢复其中一个,它当然不干。解决办法是用 RESTORE HEADERONLY 先看一眼备份集里到底有几个家族成员。命令不长:
RESTORE HEADERONLY FROM DISK = 'D:\backup\orderdb.bak' 结果里 FamilyCount 那一列如果是 2 或者 3,你就得把所有分片都找齐,然后写 RESTORE DATABASE ... FROM DISK = 'part1.bak', DISK = 'part2.bak'。客户那次就是两个分片,另一个文件被运维挪到别的目录去了,找回来之后十分钟恢复完毕。
另一个高频坑是逻辑文件名冲突。你还原到一个新库,比如 OrderDB_Test,但备份文件里记录的物理路径还是老库的 D:\Data\OrderDB.mdf。直接还原会报“文件已存在”或者干脆覆盖掉生产库。正确做法是用 WITH MOVE 子句重新映射:
RESTORE DATABASE OrderDB_Test FROM DISK = 'D:\backup\orderdb.bak' WITH MOVE 'OrderDB' TO 'D:\Data\OrderDB_Test.mdf', MOVE 'OrderDB_Log' TO 'D:\Data\OrderDB_Test_Log.ldf', RECOVERY 那个 RECOVERY 不是必须的,默认就是它。但如果你在还原一个日志链,或者需要继续应用差异备份,就得用 NORECOVERY。我见过有人做日志传送,还原完整备份时没加 NORECOVERY,结果后续的差异备份死活恢复不上去,卡了一下午。
还有一种情况:备份文件本身是坏的。不是文件损坏,是备份过程中磁盘满了或者网络断了,SQL Server 没报错,但 .bak 里缺页。恢复的时候走到一半报“页校验和失败”。这时候可以试试 WITH CONTINUE_AFTER_ERROR,强行跳过坏页,但恢复出来的库可能逻辑不一致,只适合救急导出数据,别直接上线。更稳的办法是平时开启 CHECKSUM 备份选项,让 SQL Server 在写备份时就算校验和,恢复时自动验证。代价是备份慢个 5% 到 10%,但换来的是你知道备份到底能不能用。
说到能不能用,我自己的习惯是:每次备份完,立刻在测试实例上还原一次,哪怕只是 RESTORE VERIFYONLY。命令就一行:
RESTORE VERIFYONLY FROM DISK = 'D:\backup\orderdb.bak' 它不真正恢复数据,只检查备份集完不完整、能不能读。跑一遍几秒钟,比真出事的时候抓瞎强太多。很多团队把备份当任务完成,从不验证,等到要恢复才发现文件是空的、或者权限不对、或者版本不兼容——SQL Server 2016 的备份拿到 2012 上恢复,直接报错,没得商量。
权限问题也常被忽略。SQL Server 服务账户对备份文件所在的目录必须有读权限,对还原目标目录必须有写权限。网络路径更麻烦,服务账户往往是 NT Service\MSSQLSERVER,它访问 UNC 路径 \\nas\backup 需要域账户或者显式授权。我碰到过一次,本地管理员能打开那个共享,但 SQL Server 就是报“拒绝访问”。查了半天,服务账户是虚拟账户,没域权限。最后把备份文件拷到本地磁盘才恢复成功。
恢复本身不复杂,复杂的是恢复之前你得清楚:备份是谁做的、怎么做的、有几个文件、逻辑名是什么、目标实例版本对不对、磁盘空间够不够。这些信息平时不整理,出事的时候就只能靠 RESTORE HEADERONLY 和 RESTORE FILELISTONLY 一条条去猜。我现在的做法是,每个库的备份脚本里都加上 CHECKSUM 和 STATS = 5,备份完自动跑一次 VERIFYONLY,结果写日志。看起来啰嗦,但凌晨三点被叫醒的时候,你只想点一下“还原”就能睡觉。
很赞哦!(63)







