上周有个朋友半夜给我打电话,声音听着都慌了——他公司一个项目的数据库突然崩了,数据丢了大半,备份文件只有一个 .bak 后缀的文件躺在那里。他问我:“这玩意儿怎么还原啊?”电话那头键盘噼里啪啦响,估计是边问边在百度上翻教程。这种场景我见过太多次了,做媒体的这些年,隔三差五就有人来问类似的问题。 .bak 文件,说白了就是数据库的“急救包”,但很多人手里攥着急救包,却不懂怎么拆开用。

先搞清楚一个事:你手上的 .bak 文件是哪家的“孩子”?数据库厂商不同,.bak 文件的“脾气”也完全不一样。SQL Server 的 .bak 文件是它自家的备份格式,专门给 T‑SQL 命令和 Management Studio 用的。MySQL 或 PostgreSQL 的备份有时也会用 .bak 后缀,但底层可能是 mysqldump 导出的 SQL 脚本,也可能是 pgdump 的自定义格式。最坑的是,有人拿到的 .bak 文件其实是某个软件自动生成的压缩包,里面装的可能是 CSV 或 Excel。所以第一步别急着敲命令,先看看文件头——用记事本打开瞅一眼,如果是 “TAPE” 开头的,那是 SQL Server 的;要是直接能看到 “CREATE TABLE” 之类的 SQL 语句,那多半是文本格式的备份。
如果是 SQL Server 的 .bak 文件,还原流程其实挺标准的,但新手最容易卡在权限和路径上。假设你装了 SQL Server Management Studio(SSMS),打开它,连上你的实例,右键点击“数据库”,选“还原数据库”。弹出窗口里,在“源”那一栏选择“设备”,然后点三个点的浏览按钮,找到你的 .bak 文件。这里有个坑:很多人以为选了文件就万事大吉,结果点确定后报错,说“介质集不完整”或“无法访问文件”。原因是 SQL Server 服务账户可能没有读取该文件的权限。解决办法是把 .bak 文件复制到 SQL Server 默认的备份目录(通常是 C:Program FilesMicrosoft SQL ServerMSSQLBackup),或者直接给文件所在文件夹授予 SQL Server 服务账户读取权限。这类细节在教程里少提,但实际操作时常卡你半天。
命令行还原更直接,也更“装逼”。打开 SSMS 的查询窗口,或者直接用 sqlcmd 工具,敲一行 RESTORE DATABASE 命令:WITH REPLACE 表示允许覆盖已有数据库,RECOVERY 则让数据库恢复到可用状态。如果只想把备份里的数据捞出来而不覆盖现有库,可以加上 MOVE 参数指定新的数据文件和日志文件路径,例如:这一步特别适合只想提取部分数据的人,比如只要一个表或几行记录。
MySQL 的 .bak 文件通常就是个 SQL 文本文件,还原起来简单粗暴。打开命令行,进入 MySQL 的 bin 目录,然后执行:如果 .bak 文件是压缩的(比如 .gz 或 .zip),先解压,或者用管道直接解压再导入:需要注意的是:如果文件里包含了创建数据库的语句(如 ),在导入前要确保目标库已经存在,或者先导入到默认库再手动创建。更省事的办法是用 MySQL Workbench,连上实例后点 “Server → Data Import”,选择 “Import from Self‑Contained File”,指定 .bak 文件并选定目标库,点 “Start Import”。不过 Workbench 导入大文件时容易卡死,超过 1 GB 的文件还是建议用命令行。
PostgreSQL 的情况稍微复杂点。它的 .bak 文件可能是 pgdump 生成的自定义格式(也常用 .dump 后缀),也可能是纯 SQL 文本。如果是文本格式,恢复命令类似 MySQL:如果是自定义格式,就得用 pgrestore:pgrestore 默认会尝试重建整个数据库,包括索引、约束、触发器等。如果目标库里已有同名对象,建议加上 先清理旧的,或者使用 避免报错。想只恢复某个表,可以加 参数,例如:这对只想恢复部分数据的人来说,比全量恢复后再删减要省事得多。
跨数据库平台还原 .bak 文件?这事我劝你三思。比如手里有一个 SQL Server 的 .bak 文件,想直接还原到 MySQL,显然行不通。但也不是完全没有办法:可以先在 SQL Server 上把 .bak 文件还原到临时库,然后用 SSMS 的 “导出数据”功能把表结构和数据导出为脚本,或者通过 ODBC 连接把数据转移到 MySQL。更麻烦但更干净的方法是使用 ETL 工具,如 SQL Server Integration Services(SSIS)或第三方的 Navicat、DBeaver,它们都支持跨库迁移。不过数据类型的映射容易出问题,例如 SQL Server 的 datetime2 与 MySQL 的 datetime 精度不同,nvarchar(max) 在 MySQL 里会变成 text,需要手动调整。所以如果不是必须跨平台,最好还是用原生的还原方式,省心省力。
说个实在的:.bak 文件还原成功只是第一步,更关键的是验证数据完整性。很多人还原完就以为万事大吉,结果几天后发现某个表少了几行,或者存储过程编译失败。我的习惯是还原后立刻跑几个典型查询,比如查最近 100 条订单记录,核对总数和金额;或者执行关键的存储过程,看看有没有报错。如果数据库有外键约束,还要检查引用关系是否完整。更稳妥的做法是使用 DBCC CHECKDB(SQL Server)或相应的完整性检查工具做一次全库检查。虽然这些步骤听起来繁琐,但能避免你半夜再被电话吵醒——毕竟数据库出问题,总是“不出则已,一出就是大问题”。


