SQL Server 单表恢复是什么
SQL Server 没有「只还原一张表」的命令:误删表或误改数据时,常规做法是把完整备份以新库名还原到同一实例(用 MOVE 指定新的数据与日志文件位置),再从临时库把目标表的数据导回生产库。整个过程不覆盖生产库,生产侧只承受导回动作带来的影响。
基本信息
| 适用平台 | SQL Server(RESTORE ... WITH MOVE 语法通用) |
|---|---|
| 前提条件 | 有可用的完整备份,且实例磁盘空间足够放一份副本 |
| 关键参数 | MOVE 指定数据与日志文件的新位置 |
| 常用选项 | RECOVERY 与 NORECOVERY、STOPAT 时间点还原 |
| 回导方式 | INSERT ... SELECT 或 MERGE,配合 NOT EXISTS 保证幂等 |
| 收尾动作 | 验证完成后删除临时库,避免占用空间与合规风险 |
典型使用场景
- 误删表或误删部分行后精确找回数据
- 误更新覆盖了正确数据,需要回到操作前的行版本
- 有审计要求,需要保留完整的恢复过程记录
- 需要在指定时间点还原时,用日志备份配合 STOPAT
- 演练:在完全不影响生产的前提下验证备份可恢复性
还原到新库并导回数据
还原到新库并导回数据
# 1) 把完整备份还原成新库(库名与文件名都要改)
RESTORE DATABASE [AppDB_rescue] FROM DISK = N'D:\backup\AppDB-full.bak' WITH MOVE N'AppDB' TO N'D:\data\AppDB_rescue.mdf', MOVE N'AppDB_log' TO N'D:\data\AppDB_rescue_log.ldf', RECOVERY, STATS = 10;
# 2) 只导回缺失的行(幂等写法)
INSERT INTO [AppDB].[dbo].[Orders] (Id, OrderNo, CreatedAt) SELECT s.Id, s.OrderNo, s.CreatedAt FROM [AppDB_rescue].[dbo].[Orders] AS s WHERE NOT EXISTS (SELECT 1 FROM [AppDB].[dbo].[Orders] AS t WHERE t.Id = s.Id);
# 3) 核对行数与关键业务口径
SELECT COUNT(*) FROM [AppDB].[dbo].[Orders];
# 4) 确认无误后清理临时库
DROP DATABASE [AppDB_rescue];还原与导回要点读法
| 要点 | 作用 | 注意 |
|---|---|---|
| MOVE | 把数据与日志文件放到新路径 | 漏写会尝试使用生产库文件路径,直接失败或造成更大事故 |
| RECOVERY / NORECOVERY | 还原后数据库是否可用 | 还要继续还原日志备份时必须用 NORECOVERY |
| STOPAT | 还原到指定时间点 | 依赖完整的日志备份链,缺链会直接报错 |
| 幂等导回 | 用 NOT EXISTS 或 MERGE 避免重复插入 | 简单 INSERT ... SELECT 会把重复行写进去 |
| 临时库清理 | 验证后删除临时库 | 长期留着占空间,也扩大数据可访问面 |
导回前先核对表结构与索引:临时库与生产库版本不一致时,导回语句要显式列出列名,避免依赖列顺序。
还原过程只读不写生产库,风险集中在导回那一步:先在临时库上把导回语句跑通并核对行数,再对生产执行。