SQL Server中.bak文件导入与还原的完整指南

17 次阅读

SQL Server的.bak文件是数据库备份文件,通常由SQL Server通过完整备份、差异备份等方式生成。当服务器迁移、数据库恢复、测试环境搭建或数据灾备时,经常需要将.bak文件重新导入SQL Server。需要注意的是,所谓“导入.bak文件”实际上更准确地说是还原数据库备份,并不是像导入Excel或CSV那样直接读取文件。

掌握SQL Server .bak文件的还原方法,可以有效处理数据库迁移、服务器重装、测试数据恢复等场景。实际操作过程中,最容易遇到的问题包括备份文件路径、逻辑文件名、物理文件路径冲突、数据库已存在以及SQL Server版本兼容性等。

一、SQL Server的.bak文件是什么

.bak通常是SQL Server数据库备份文件的常见扩展名。通过SQL Server Management Studio(SSMS)或者T-SQL执行数据库备份后,可以生成类似下面的文件:

D:BackupMyDatabase.bak

其中可能包含:

  • 完整数据库备份

  • 差异数据库备份

  • 事务日志备份

  • 多个备份集

最常见的场景是完整数据库备份。例如:

SQL
BACKUP DATABASE MyDatabase
TO DISK = 'D:BackupMyDatabase.bak'
WITH INIT;

生成的.bak文件并不是普通的数据文件,不能直接通过文件资源管理器打开,也不能使用CREATE DATABASE直接加载。恢复时需要SQL Server数据库引擎读取备份集,并根据其中记录重新创建数据库结构和数据。

二、使用SSMS还原.bak文件

对于日常数据库管理,使用SQL Server Management Studio图形界面还原数据库最直观。

首先启动SSMS,连接目标SQL Server实例,然后在左侧对象资源管理器中找到:

数据库

右键选择:

还原数据库...

打开数据库还原窗口后,可以看到“源”和“目标”相关设置。

1. 选择备份源

在“源”区域选择:

设备

然后点击右侧的浏览按钮,添加.bak文件。

例如:

D:BackupMyDatabase.bak

选择文件后,SQL Server会尝试读取其中的备份集。

如果文件正常且SQL Server能够访问该路径,界面中通常会显示备份日期、备份类型、数据库名称等信息。

2. 选择目标数据库

在“目标”区域设置要恢复的数据库名称。

例如原数据库叫:

MyDatabase

可以直接恢复成:

MyDatabase

也可以恢复成其他名称:

MyDatabase_Test

测试环境中经常采用第二种方式,这样不会覆盖生产数据库。

3. 检查备份集

选择需要还原的备份集后,确认备份类型为完整数据库备份。

如果.bak中包含多个备份集,不要仅凭文件名判断应该使用哪一个,而应该根据备份时间、数据库名称和备份类型进行选择。

4. 检查文件路径

这是.bak恢复过程中非常重要的一步。

切换到“文件”页面,可以看到数据库中的逻辑文件及对应的物理路径,例如:

MyDatabase
MyDatabase_log

原服务器可能使用:

C:Program FilesMicrosoft SQL ServerMSSQLData

而新服务器可能没有这个目录。如果直接还原,可能出现文件路径不存在的错误。

此时可以修改为目标服务器实际存在的目录,例如:

D:SQLDataMyDatabase.mdf
D:SQLDataMyDatabase_log.ldf

确认路径后再执行还原。

5. 处理现有数据库

如果目标数据库已经存在,需要根据实际情况决定是否覆盖。

在“选项”页面通常可以看到:

覆盖现有数据库(WITH REPLACE)

以及:

关闭到目标数据库的现有连接

如果确定旧数据库可以被替换,可以勾选相应选项。

不过生产环境操作时一定要谨慎。WITH REPLACE会绕过部分安全提示,如果误操作,可能导致现有数据库被覆盖。

三、使用T-SQL还原.bak文件

对于服务器部署、自动化运维和批量操作,使用T-SQL通常比图形界面更加方便。

最简单的完整数据库还原语句如下:

SQL
RESTORE DATABASE MyDatabase
FROM DISK = 'D:BackupMyDatabase.bak'
WITH
    RECOVERY;

其中:

  • RESTORE DATABASE表示还原数据库;

  • MyDatabase是目标数据库名称;

  • FROM DISK指定.bak文件;

  • RECOVERY表示完成恢复并使数据库进入正常可用状态。

如果备份文件路径中包含空格,可以直接使用单引号包裹完整路径。

例如:

SQL
RESTORE DATABASE MyDatabase
FROM DISK = 'D:SQL BackupMyDatabase.bak'
WITH RECOVERY;

四、先查看.bak文件中的逻辑文件名

实际恢复时,不建议直接猜测数据库文件名称。可以先使用RESTORE FILELISTONLY查看备份文件内部的信息:

SQL
RESTORE FILELISTONLY
FROM DISK = 'D:BackupMyDatabase.bak';

执行后可以看到类似以下信息:

LogicalName        PhysicalName
-----------------  ----------------------------------
MyDatabase         C:MSSQLDataMyDatabase.mdf
MyDatabase_log     C:MSSQLDataMyDatabase_log.ldf

这里需要重点关注LogicalName。

逻辑文件名与服务器当前磁盘路径并不是一回事。使用WITH MOVE恢复数据库时,需要填写这里的逻辑文件名。

五、使用WITH MOVE解决数据库文件路径问题

如果新服务器的数据目录与原服务器不同,推荐使用WITH MOVE。

例如:

SQL
RESTORE DATABASE MyDatabase
FROM DISK = 'D:BackupMyDatabase.bak'
WITH
    MOVE 'MyDatabase'
    TO 'D:SQLDataMyDatabase.mdf',
    MOVE 'MyDatabase_log'
    TO 'D:SQLDataMyDatabase_log.ldf',
    RECOVERY;

这里:

SQL
MOVE 'MyDatabase'

对应的是备份文件中的逻辑文件名,而:

SQL
TO 'D:SQLDataMyDatabase.mdf'

则是新服务器上的实际物理文件路径。

因此,比较完整的操作流程是:

SQL
RESTORE FILELISTONLY
FROM DISK = 'D:BackupMyDatabase.bak';

先获取逻辑文件名,再根据目标服务器实际目录执行:

SQL
RESTORE DATABASE MyDatabase
FROM DISK = 'D:BackupMyDatabase.bak'
WITH
    MOVE 'MyDatabase' TO 'D:SQLDataMyDatabase.mdf',
    MOVE 'MyDatabase_log' TO 'D:SQLDataMyDatabase_log.ldf',
    RECOVERY;

这种方式尤其适合服务器迁移。

六、还原到一个新的数据库名称

如果希望保留原数据库,同时从.bak创建一个测试数据库,可以直接指定新的数据库名称。

例如:

SQL
RESTORE DATABASE MyDatabase_Test
FROM DISK = 'D:BackupMyDatabase.bak'
WITH
    MOVE 'MyDatabase'
    TO 'D:SQLDataMyDatabase_Test.mdf',
    MOVE 'MyDatabase_log'
    TO 'D:SQLDataMyDatabase_Test_log.ldf',
    RECOVERY;

需要注意,数据库名称虽然改成了MyDatabase_Test,但备份内部的逻辑文件名仍然可能是:

MyDatabase
MyDatabase_log

所以MOVE参数中的逻辑名称不能简单地跟着目标数据库名称修改,而应该以RESTORE FILELISTONLY查询结果为准。

七、数据库已存在时如何还原

如果目标数据库已经存在,直接执行还原可能出现类似错误:

Exclusive access could not be obtained because the database is in use.

原因通常是当前数据库存在其他连接。

可以先将数据库设置为单用户模式:

SQL
ALTER DATABASE MyDatabase
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;

然后执行恢复:

SQL
RESTORE DATABASE MyDatabase
FROM DISK = 'D:BackupMyDatabase.bak'
WITH
    REPLACE,
    RECOVERY;

恢复完成后,再将数据库切换回多用户模式:

SQL
ALTER DATABASE MyDatabase
SET MULTI_USER;

完整流程可以写成:

SQL
ALTER DATABASE MyDatabase
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;

RESTORE DATABASE MyDatabase
FROM DISK = 'D:BackupMyDatabase.bak'
WITH
    REPLACE,
    RECOVERY;

ALTER DATABASE MyDatabase
SET MULTI_USER;

生产环境执行这类操作前,应确认数据库连接情况,并确保已有数据已经完成必要的备份。

八、还原前检查SQL Server版本

数据库备份还原存在版本兼容问题。

一般情况下,可以将较低版本SQL Server创建的数据库备份还原到较高版本SQL Server。例如从旧版本SQL Server迁移到较新版本。

但反过来通常不支持直接还原。例如较新版本SQL Server创建的.bak,不能直接恢复到更老版本的SQL Server实例。

因此,当出现类似:

The database was backed up on a server running version ...
That version is incompatible with this server.

首先应该检查源SQL Server和目标SQL Server的版本。

可以执行:

SQL
SELECT
    @@VERSION;

或者:

SQL
SELECT
    SERVERPROPERTY('ProductVersion') AS ProductVersion,
    SERVERPROPERTY('ProductLevel') AS ProductLevel,
    SERVERPROPERTY('Edition') AS Edition;

如果目标服务器版本低于备份数据库所在的SQL Server版本,通常需要通过脚本生成、数据导出等方式完成降版本迁移,而不能直接使用.bak恢复。

九、检查.bak文件是否有效

拿到别人提供的.bak文件后,不建议直接进行正式恢复,可以先检查备份文件。

使用:

SQL
RESTORE VERIFYONLY
FROM DISK = 'D:BackupMyDatabase.bak';

如果验证成功,说明SQL Server能够正常识别该备份文件。

还可以查看备份文件包含的备份集:

SQL
RESTORE HEADERONLY
FROM DISK = 'D:BackupMyDatabase.bak';

这个命令能够帮助确认:

  • 备份数据库名称

  • 备份类型

  • 备份开始时间

  • 备份结束时间

  • 备份集编号

  • SQL Server版本信息

对于来源不明确的备份文件,这一步非常有价值。

十、常见的.bak还原失败原因

1. 找不到备份文件

错误通常与文件路径有关,例如:

Cannot open backup device

需要检查.bak文件是否确实存在,以及SQL Server服务账户是否有权限读取该目录。

需要特别注意,T-SQL中的路径是SQL Server服务器所在机器的路径,并不是执行SSMS客户端电脑的路径。

例如:

SQL
RESTORE DATABASE MyDatabase
FROM DISK = 'C:BackupMyDatabase.bak';

如果SSMS连接的是远程SQL Server,那么这里的C:Backup指的是远程SQL Server服务器上的目录。

2. Operating system error 5

如果出现:

Operating system error 5(Access is denied.)

通常意味着SQL Server服务账户没有访问备份文件所在目录的权限。

解决时需要检查:

  • .bak所在目录权限;

  • SQL Server服务运行账户;

  • 文件夹的读取权限;

  • 网络共享路径权限。

不要只检查当前Windows用户是否能够打开文件,因为真正读取.bak的是SQL Server服务进程。

3. 数据库文件已存在

如果还原时出现类似:

The file ... cannot be overwritten.
It is being used by database ...

说明备份中的数据文件与目标环境已有文件发生冲突。

通常可以通过WITH MOVE指定新的数据文件路径,或者确认确实需要覆盖已有数据库后使用WITH REPLACE。

4. 数据库正在使用

如果出现无法获得独占访问权限的问题,需要检查是否存在应用程序、连接池、查询窗口等连接。

可以使用:

SQL
ALTER DATABASE MyDatabase
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;

然后执行恢复。

5. 备份文件损坏

如果出现备份介质读取错误或者备份集损坏,需要检查.bak文件是否完整。

可以先执行:

SQL
RESTORE VERIFYONLY
FROM DISK = 'D:BackupMyDatabase.bak';

如果验证失败,应重新获取可靠的备份文件,而不是反复尝试恢复损坏的文件。

十一、从网络共享路径还原.bak

如果备份文件存放在网络共享目录,例如:

\192.168.1.100ackupMyDatabase.bak

可以尝试:

SQL
RESTORE DATABASE MyDatabase
FROM DISK = '\192.168.1.100ackupMyDatabase.bak'
WITH RECOVERY;

但此时需要确保SQL Server服务账户能够访问该共享目录。

Windows资源管理器中能够访问共享目录,并不代表SQL Server服务账户也具有相同权限。

在企业环境中,更稳妥的方式通常是先将.bak复制到SQL Server服务器本地磁盘,再执行恢复操作。

十二、还原完成后进行数据库检查

数据库恢复成功并不意味着所有工作已经结束。还原完成后,可以执行:

SQL
SELECT
    name,
    state_desc,
    recovery_model_desc
FROM sys.databases
WHERE name = 'MyDatabase';

确认数据库状态是否为:

ONLINE

然后可以运行DBCC检查:

SQL
DBCC CHECKDB ('MyDatabase')
WITH NO_INFOMSGS;

如果没有发现数据库一致性问题,说明恢复后的数据库结构和数据页检查基本正常。

对于重要生产数据库,还应进一步检查:

  • 关键业务表数据;

  • 用户和登录账户;

  • 数据库权限;

  • SQL Agent作业;

  • 存储过程;

  • 触发器;

  • 定时任务;

  • 外部依赖;

  • 应用程序连接字符串。

十三、还原数据库后登录用户可能无法使用

数据库从另一台SQL Server迁移过来后,有时会出现数据库用户存在,但无法正常登录的问题。

这是因为SQL Server实例级登录名与数据库内部用户并不是完全相同的对象。

可以查看数据库用户:

SQL
USE MyDatabase;

SELECT
    name,
    type_desc
FROM sys.database_principals
WHERE type IN ('S', 'U', 'G');

如果出现登录名与数据库用户映射不一致的情况,需要根据实际账户重新建立映射。

例如:

SQL
ALTER USER appuser
WITH LOGIN = appuser;

具体处理方式取决于SQL Server版本、用户类型以及原服务器的账户配置。

十四、完整的T-SQL还原示例

假设现在有:

D:BackupOrderDB.bak

需要恢复到:

D:SQLData

数据库名称为:

OrderDB_Test

首先查询备份中的逻辑文件:

SQL
RESTORE FILELISTONLY
FROM DISK = 'D:BackupOrderDB.bak';

假设返回:

OrderDB
OrderDB_log

那么可以执行:

SQL
RESTORE DATABASE OrderDB_Test
FROM DISK = 'D:BackupOrderDB.bak'
WITH
    MOVE 'OrderDB'
    TO 'D:SQLDataOrderDB_Test.mdf',
    MOVE 'OrderDB_log'
    TO 'D:SQLDataOrderDB_Test_log.ldf',
    RECOVERY,
    STATS = 10;

其中:

SQL
STATS = 10

表示每完成10%的恢复进度输出一次进度信息,方便观察大型数据库的恢复过程。

十五、还原大型数据库时的注意事项

大型.bak文件恢复可能需要较长时间,不能简单地认为SSMS没有响应就是程序出现问题。

恢复时间通常与以下因素有关:

  • .bak文件大小;

  • 磁盘读写速度;

  • CPU性能;

  • 数据库文件数量;

  • 网络存储性能;

  • 备份文件所在位置;

  • 目标磁盘剩余空间。

正式恢复前最好确认目标磁盘有足够空间。

尤其需要注意,.bak文件只有几十GB,并不代表恢复后数据库只需要几十GB。数据库中的.mdf、.ndf、.ldf文件可能占用远大于备份文件本身的空间。

可以通过:

SQL
RESTORE FILELISTONLY
FROM DISK = 'D:BackupOrderDB.bak';

提前了解备份中的文件信息和大小。

十六、.bak文件恢复的推荐操作流程

一个比较稳妥的SQL Server .bak恢复流程可以概括为:

确认SQL Server版本
        ↓
确认.bak文件完整
        ↓
RESTORE VERIFYONLY
        ↓
RESTORE HEADERONLY
        ↓
RESTORE FILELISTONLY
        ↓
确认逻辑文件名称
        ↓
确认目标磁盘空间
        ↓
确认SQL Server账户权限
        ↓
确定目标数据库名称
        ↓
使用WITH MOVE规划文件路径
        ↓
执行RESTORE DATABASE
        ↓
检查数据库ONLINE状态
        ↓
执行DBCC CHECKDB
        ↓
检查用户、权限和业务数据

对于测试数据库,可以直接恢复成新的数据库名称,避免影响原有数据。对于生产数据库,则应先确认备份来源、恢复时间点、数据库连接情况以及回滚方案。

十七、SSMS和T-SQL应该如何选择

SSMS更适合临时操作和可视化管理。通过还原数据库窗口,可以直观看到备份集、文件路径和恢复选项,适合不熟悉T-SQL语法的用户。

T-SQL则更适合:

  • 数据库迁移;

  • 自动化部署;

  • 批量恢复;

  • 运维脚本;

  • 定时任务;

  • 服务器环境配置。

实际工作中,可以先通过SSMS熟悉恢复流程,再将稳定的操作转换成T-SQL脚本,从而提高数据库恢复的一致性和可重复性。

SQL Server .bak文件的导入本质上是数据库恢复过程。最关键的并不是记住某一个按钮的位置,而是理解备份文件、逻辑文件、物理文件和目标数据库之间的关系。遇到跨服务器恢复时,优先使用RESTORE FILELISTONLY确认逻辑文件,再结合WITH MOVE指定新的物理路径,通常能够解决大部分数据库文件路径冲突问题。

对于重要数据库,还应坚持“先验证、后恢复”的原则,通过RESTORE VERIFYONLY和RESTORE HEADERONLY检查备份状态,并在恢复完成后使用DBCC CHECKDB进行一致性检查。这样不仅能够完成.bak文件的导入,还能降低数据库迁移和恢复过程中出现数据问题的风险。