以下是一套完整的 SQL Server 数据库恢复流程脚本,针对启用了 Change Data Capture (CDC) 的数据库,确保 正确恢复 CDC 元数据 并避免错误(如你之前遇到的 4902 错误)。
🎯 场景假设
-
数据库名称:
main_db
-
备份文件:
- 全量备份:
D:\backups\main_db_full.bak
- 日志备份(可选):
D:\backups\main_db_log.trn
- 全量备份:
-
恢复目标服务器已有同名数据库,可以覆盖
-
保留 CDC(如果你不想保留,可以看“简化版本”)
✅ 1. 保留 CDC 的恢复脚本(推荐)
-- 设置为单用户模式,避免连接冲突(如果数据库已存在)
ALTER DATABASE [main_db] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
-- 删除已存在的数据库(可选,视情况使用)
DROP DATABASE IF EXISTS [main_db];
GO
-- 恢复全量备份(不立即 RECOVERY,保留 CDC 元数据)
RESTORE DATABASE [main_db]
FROM DISK = N'D:\backups\main_db_full.bak'
WITH
MOVE 'main_db' TO 'D:\MSSQL\Data\main_db.mdf',
MOVE 'main_db_log' TO 'D:\MSSQL\Data\main_db_log.ldf',
NORECOVERY, -- 允许接下来恢复日志
KEEP_CDC, -- 保留 CDC 元数据
REPLACE;
GO
-- 恢复日志备份(如果有)
RESTORE LOG [main_db]
FROM DISK = N'D:\backups\main_db_log.trn'
WITH NORECOVERY;
GO
-- 最后一步:恢复数据库为可用状态(COMMIT)
RESTORE DATABASE [main_db] WITH RECOVERY;
GO
-- 检查 CDC 是否启用
SELECT name, is_cdc_enabled FROM sys.databases WHERE name = 'main_db';
GO
-- 可选:检查 CDC 表是否存在
USE [main_db];
SELECT * FROM sys.tables WHERE name LIKE 'cdc%';
⚠️ 如果不想保留 CDC,可使用此简化版:
-- 恢复数据库并关闭 CDC(恢复后立即禁用)
RESTORE DATABASE [main_db]
FROM DISK = N'D:\backups\main_db_full.bak'
WITH
MOVE 'main_db' TO 'D:\MSSQL\Data\main_db.mdf',
MOVE 'main_db_log' TO 'D:\MSSQL\Data\main_db_log.ldf',
REPLACE,
RECOVERY;
GO
-- 禁用 CDC(慎用)
EXEC sys.sp_cdc_disable_db;
GO
🧪 其他建议
- 确保执行用户是
sysadmin
或至少对数据库具有db_owner
权限 - 如果你使用的是 Docker 容器部署 MSSQL,可将备份文件挂载到容器中再运行恢复脚本
MOVE
语句中逻辑文件名需要与你备份中的逻辑文件匹配(可先执行如下查询):
RESTORE FILELISTONLY FROM DISK = N'D:\backups\main_db_full.bak';
❓你需要我:
- 根据你的实际路径/文件名生成完整脚本?
- 添加 Docker 场景的挂载/还原命令?
- 包含 CDC 重建逻辑(如果表已损坏)?