Skip to content

SQLServer 全量恢复

全量恢复概述

什么是全量恢复

全量恢复是指使用完整备份来恢复数据库的过程,它将数据库恢复到完整备份完成时的状态。全量恢复是SQLServer恢复操作的基础,其他恢复类型(如差异恢复、时间点恢复)都需要先执行全量恢复。

全量恢复的适用场景

  1. 数据库完全损坏:当数据库文件损坏或丢失时,需要使用完整备份进行全量恢复
  2. 创建测试环境:使用生产数据库的完整备份创建测试环境
  3. 数据库迁移:将数据库从一个服务器迁移到另一个服务器
  4. 恢复到特定时间点:作为差异恢复或时间点恢复的基础步骤
  5. 误操作恢复:当发生严重误操作时,需要从完整备份恢复数据库

全量恢复前准备

恢复环境检查

  1. 磁盘空间检查

    sql
    -- 检查恢复目标磁盘可用空间
    EXEC xp_fixeddrives;
    
    -- 查询完整备份文件大小,估算所需空间
    RESTORE FILELISTONLY FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak';
  2. 权限检查

    • 执行恢复操作的用户需要具有RESTORE DATABASE权限
    • 对于系统数据库,需要sysadmindbcreator角色
  3. 数据库状态检查

    sql
    -- 检查数据库当前状态
    SELECT 
        name AS DatabaseName,
        state_desc,
        recovery_model_desc
    FROM sys.databases
    WHERE name = 'AdventureWorks2022';
  4. 备份文件检查

    sql
    -- 验证备份文件完整性
    RESTORE VERIFYONLY FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' WITH CHECKSUM;

恢复计划制定

  1. 确定恢复目标:明确恢复后的数据库名称、位置和状态
  2. 选择备份文件:选择最新的、完整的备份文件
  3. 规划恢复步骤:根据恢复场景确定恢复步骤
  4. 估算恢复时间:根据备份文件大小和系统性能估算恢复时间
  5. 准备回滚方案:制定恢复失败时的回滚方案

全量恢复实施步骤

使用SSMS进行全量恢复

  1. 打开SQL Server Management Studio,连接到SQL Server实例
  2. 展开"数据库"节点
  3. 右键单击"数据库"节点,选择"还原数据库..."
  4. 在"还原数据库"对话框中:
    • 选择"源"为"设备",点击"..."按钮
    • 在"选择备份设备"对话框中,点击"添加"按钮,选择备份文件,点击"确定"
    • 在"目标"区域,选择目标数据库(可以是现有数据库或新数据库)
    • 在"还原计划"区域,选择要还原的备份集
    • 切换到"选项"页,配置恢复选项:
      • 恢复状态:选择"RESTORE WITH RECOVERY"(如果只进行全量恢复)
      • 覆盖现有数据库:如果恢复到现有数据库,勾选此选项
      • 移动数据库文件:如果需要更改数据文件和日志文件的位置,配置"将数据库文件还原为"选项
    • 点击"确定"执行恢复

使用T-SQL进行全量恢复

基本全量恢复

sql
-- 基本全量恢复
RESTORE DATABASE [AdventureWorks2022] 
FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
WITH RECOVERY, 
NOUNLOAD, STATS = 10;

恢复到新数据库

sql
-- 恢复到新数据库
RESTORE DATABASE [AdventureWorks2022_Test] 
FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
WITH RECOVERY, 
MOVE N'AdventureWorks2022' TO N'D:\Data\AdventureWorks2022_Test.mdf', 
MOVE N'AdventureWorks2022_log' TO N'E:\Log\AdventureWorks2022_Test_log.ldf', 
NOUNLOAD, STATS = 10;

覆盖现有数据库

sql
-- 覆盖现有数据库
RESTORE DATABASE [AdventureWorks2022] 
FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
WITH RECOVERY, 
REPLACE, 
NOUNLOAD, STATS = 10;

恢复到NORECOVERY状态(用于后续恢复)

sql
-- 恢复到NORECOVERY状态,用于后续恢复差异备份或事务日志备份
RESTORE DATABASE [AdventureWorks2022] 
FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
WITH NORECOVERY, 
NOUNLOAD, STATS = 10;

-- 恢复差异备份
RESTORE DATABASE [AdventureWorks2022] 
FROM DISK = N'D:\Backup\AdventureWorks2022_Diff_20251227_1200.bak' 
WITH NORECOVERY, 
NOUNLOAD, STATS = 10;

-- 恢复最后一个事务日志备份,使用RECOVERY完成恢复
RESTORE LOG [AdventureWorks2022] 
FROM DISK = N'D:\Backup\AdventureWorks2022_Log_20251227_1600.trn' 
WITH RECOVERY, 
NOUNLOAD, STATS = 10;

全量恢复场景

场景1:数据库完全损坏

恢复步骤

  1. 确认数据库损坏

    sql
    -- 检查数据库状态
    SELECT name, state_desc FROM sys.databases WHERE name = 'AdventureWorks2022';
    
    -- 尝试访问数据库
    USE AdventureWorks2022;
    SELECT TOP 10 * FROM Sales.SalesOrderHeader;
  2. 停止数据库服务(如果需要):

    bash
    # Windows
    net stop MSSQLSERVER
    
    # Linux

sudo systemctl stop mssql-server


3. **恢复数据库**:
```sql
-- 恢复数据库
RESTORE DATABASE [AdventureWorks2022] 
FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
WITH RECOVERY, 
REPLACE, 
NOUNLOAD, STATS = 10;
  1. 验证恢复结果
    sql
    -- 验证数据库状态
    SELECT name, state_desc FROM sys.databases WHERE name = 'AdventureWorks2022';
    
    -- 验证数据完整性
    DBCC CHECKDB ([AdventureWorks2022]) WITH NO_INFOMSGS, ALL_ERRORMSGS;
    
    -- 验证数据内容
    SELECT TOP 10 * FROM AdventureWorks2022.Sales.SalesOrderHeader;

场景2:创建测试环境

恢复步骤

  1. 检查备份文件

    sql
    -- 验证备份文件完整性
    RESTORE VERIFYONLY FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' WITH CHECKSUM;
  2. 恢复到测试数据库

    sql
    -- 恢复到测试数据库
    RESTORE DATABASE [AdventureWorks2022_Test] 
    FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
    WITH RECOVERY, 
    MOVE N'AdventureWorks2022' TO N'D:\TestData\AdventureWorks2022_Test.mdf', 
    MOVE N'AdventureWorks2022_log' TO N'D:\TestLog\AdventureWorks2022_Test_log.ldf', 
    NOUNLOAD, STATS = 10;
  3. 配置测试数据库

    sql
    -- 修改测试数据库的恢复模式为简单恢复模式
    ALTER DATABASE [AdventureWorks2022_Test] SET RECOVERY SIMPLE;
    
    -- 收缩日志文件
    DBCC SHRINKFILE (N'AdventureWorks2022_Test_log', 10);
    
    -- 重命名数据库用户(如果需要)
    USE [AdventureWorks2022_Test];
    ALTER USER [ApplicationUser] WITH NAME = [ApplicationUser_Test];
  4. 验证测试数据库

    sql
    -- 验证数据完整性
    DBCC CHECKDB ([AdventureWorks2022_Test]) WITH NO_INFOMSGS, ALL_ERRORMSGS;
    
    -- 运行应用程序测试脚本
    EXEC [AdventureWorks2022_Test].[dbo].[usp_TestApplication];

场景3:数据库迁移

恢复步骤

  1. 在源服务器上备份数据库

    sql
    -- 在源服务器上创建完整备份
    BACKUP DATABASE [AdventureWorks2022] 
    TO DISK = N'\BackupServer\SQLBackup\AdventureWorks2022_Migration.bak' 
    WITH NOFORMAT, NOINIT, NAME = N'AdventureWorks2022-Migration Full Database Backup', 
    SKIP, NOREWIND, NOUNLOAD, STATS = 10;
  2. 在目标服务器上恢复数据库

    sql
    -- 在目标服务器上恢复数据库
    RESTORE DATABASE [AdventureWorks2022] 
    FROM DISK = N'\BackupServer\SQLBackup\AdventureWorks2022_Migration.bak' 
    WITH RECOVERY, 
    MOVE N'AdventureWorks2022' TO N'D:\Data\AdventureWorks2022.mdf', 
    MOVE N'AdventureWorks2022_log' TO N'E:\Log\AdventureWorks2022_log.ldf', 
    NOUNLOAD, STATS = 10;
  3. 迁移登录名和作业

    sql
    -- 迁移登录名(使用sp_help_revlogin存储过程)
    -- 在源服务器上运行sp_help_revlogin,生成登录名创建脚本
    -- 在目标服务器上执行生成的脚本
    
    -- 迁移SQL Server代理作业
    -- 使用SQL Server Management Studio导出作业脚本
    -- 在目标服务器上执行作业脚本
  4. 验证迁移结果

    sql
    -- 验证数据库状态
    SELECT name, state_desc FROM sys.databases WHERE name = 'AdventureWorks2022';
    
    -- 验证数据完整性
    DBCC CHECKDB ([AdventureWorks2022]) WITH NO_INFOMSGS, ALL_ERRORMSGS;
    
    -- 验证登录名和权限
    SELECT name, type_desc FROM sys.server_principals;

全量恢复最佳实践

恢复前准备

  1. 确保备份文件可用

    • 验证备份文件的完整性
    • 确保备份文件在恢复过程中不会被修改或删除
    • 对于网络备份,确保网络连接稳定
  2. 规划恢复时间

    • 估算恢复所需时间
    • 选择合适的恢复窗口(如非高峰时段)
    • 通知相关业务部门
  3. 准备恢复环境

    • 确保目标服务器有足够的磁盘空间
    • 确保目标服务器的SQL Server版本与备份文件兼容
    • 准备好恢复所需的工具和脚本

恢复过程中的最佳实践

  1. 使用NORECOVERY进行多步骤恢复

    • 如果需要进行差异恢复或事务日志恢复,使用WITH NORECOVERY选项
    • 只有在完成所有恢复步骤后,才使用WITH RECOVERY选项
  2. 监控恢复进度

    • 使用STATS选项监控恢复进度
    • 定期检查恢复状态
    • 记录恢复开始时间和完成时间
  3. 处理恢复错误

    • 如果恢复失败,查看错误信息
    • 根据错误信息采取相应措施
    • 必要时回滚恢复操作

恢复后的最佳实践

  1. 验证恢复结果

    • 检查数据库状态
    • 执行DBCC CHECKDB验证数据完整性
    • 验证关键表的数据
    • 运行应用程序测试
  2. 更新数据库配置

    • 根据需要调整数据库设置
    • 更新统计信息
    • 重建索引(如果需要)
    • 配置数据库邮件和告警
  3. 文档化恢复过程

    • 记录恢复的详细步骤
    • 记录恢复时间和结果
    • 分析恢复过程中的问题和解决方案
    • 更新灾难恢复计划

全量恢复常见问题处理

问题1:恢复过程中出现"数据库正在使用"错误

错误信息

Msg 3101, Level 16, State 1, Line 1
Exclusive access could not be obtained because the database is in use.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.

解决方案

  1. 终止数据库的所有连接:

    sql
    -- 将数据库设置为单用户模式
    ALTER DATABASE [AdventureWorks2022] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    
    -- 执行恢复
    RESTORE DATABASE [AdventureWorks2022] 
    FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
    WITH RECOVERY, 
    REPLACE, 
    NOUNLOAD, STATS = 10;
    
    -- 将数据库设置为多用户模式
    ALTER DATABASE [AdventureWorks2022] SET MULTI_USER;
  2. 或者,在恢复时使用REPLACE选项:

    sql
    RESTORE DATABASE [AdventureWorks2022] 
    FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
    WITH RECOVERY, 
    REPLACE, 
    NOUNLOAD, STATS = 10;

问题2:恢复过程中出现"备份集与数据库不兼容"错误

错误信息

Msg 3154, Level 16, State 4, Line 1
The backup set holds a backup of a database other than the existing 'AdventureWorks2022' database.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.

解决方案

  • 使用REPLACE选项覆盖现有数据库:
    sql
    RESTORE DATABASE [AdventureWorks2022] 
    FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
    WITH RECOVERY, 
    REPLACE, 
    NOUNLOAD, STATS = 10;

问题3:恢复过程中出现"磁盘空间不足"错误

错误信息

Msg 3203, Level 16, State 1, Line 1
Read on "D:\Backup\AdventureWorks2022_Full_20251227.bak" failed: 112(磁盘空间不足。)
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.

解决方案

  1. 检查目标磁盘可用空间:

    sql
    EXEC xp_fixeddrives;
  2. 释放磁盘空间或扩展磁盘容量

  3. 或者,将数据库恢复到其他磁盘:

    sql
    RESTORE DATABASE [AdventureWorks2022] 
    FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak' 
    WITH RECOVERY, 
    MOVE N'AdventureWorks2022' TO N'E:\Data\AdventureWorks2022.mdf', 
    MOVE N'AdventureWorks2022_log' TO N'F:\Log\AdventureWorks2022_log.ldf', 
    NOUNLOAD, STATS = 10;

全量恢复性能优化

优化恢复速度

  1. 使用更快的存储设备

    • 将备份文件存储在高性能存储上(如SSD)
    • 将数据库文件恢复到高性能存储上
  2. 增加恢复并行度

    • 使用多个备份设备并行恢复
    • 对于大型数据库,考虑使用文件组备份和并行恢复
  3. 禁用自动统计信息更新

    sql
    -- 恢复前禁用自动统计信息更新
    ALTER DATABASE [AdventureWorks2022] SET AUTO_UPDATE_STATISTICS OFF;
    
    -- 恢复后启用自动统计信息更新
    ALTER DATABASE [AdventureWorks2022] SET AUTO_UPDATE_STATISTICS ON;
  4. 禁用数据库快照隔离

    sql
    -- 恢复前禁用数据库快照隔离
    ALTER DATABASE [AdventureWorks2022] SET ALLOW_SNAPSHOT_ISOLATION OFF;
    ALTER DATABASE [AdventureWorks2022] SET READ_COMMITTED_SNAPSHOT OFF;

减少恢复时间

  1. 使用差异备份

    • 结合完整备份和差异备份,减少恢复时间
    • 差异备份只包含自上次完整备份以来更改的数据
  2. 优化备份策略

    • 合理设计备份频率
    • 使用备份压缩减少备份文件大小
    • 定期清理过期备份
  3. 使用加速数据库恢复(ADR)

    • SQL Server 2019及以上版本支持加速数据库恢复
    • ADR可以显著减少恢复时间,尤其是对于大型数据库
    • 启用ADR:
      sql
      ALTER DATABASE [AdventureWorks2022] SET ACCELERATED_DATABASE_RECOVERY = ON;

常见问题(FAQ)

Q1: 全量恢复和差异恢复有什么区别?

A: 全量恢复使用完整备份恢复数据库,将数据库恢复到完整备份完成时的状态。差异恢复使用差异备份恢复数据库,将数据库恢复到差异备份完成时的状态,差异备份只包含自上次完整备份以来更改的数据。差异恢复必须在全量恢复之后执行。

Q2: 如何确定备份文件的内容?

A: 可以使用RESTORE FILELISTONLY和RESTORE HEADERONLY命令查看备份文件的内容:

sql
-- 查看备份文件中的数据库文件列表
RESTORE FILELISTONLY FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak';

-- 查看备份文件的头信息
RESTORE HEADERONLY FROM DISK = N'D:\Backup\AdventureWorks2022_Full_20251227.bak';

Q3: 如何恢复到不同的SQL Server版本?

A: SQL Server支持向下兼容恢复,即可以将低版本SQL Server的备份恢复到高版本SQL Server,但不支持向上兼容恢复。例如,可以将SQL Server 2019的备份恢复到SQL Server 2022,但不能将SQL Server 2022的备份恢复到SQL Server 2019。

Q4: 恢复过程中可以取消吗?

A: 恢复过程中可以取消,但取消后数据库可能处于不一致状态,需要重新执行恢复操作。建议在恢复前仔细规划,避免中途取消。

Q5: 如何验证恢复后的数据完整性?

A: 可以通过以下方法验证恢复后的数据完整性:

  1. 执行DBCC CHECKDB命令:
    sql
    DBCC CHECKDB ([AdventureWorks2022]) WITH NO_INFOMSGS, ALL_ERRORMSGS;
  2. 验证关键表的数据:
    sql
    SELECT COUNT(*) FROM AdventureWorks2022.Sales.SalesOrderHeader;
    SELECT TOP 10 * FROM AdventureWorks2022.Sales.SalesOrderDetail;
  3. 运行应用程序测试脚本:
    sql
    EXEC AdventureWorks2022.dbo.usp_TestApplication;

Q6: 如何提高全量恢复的可靠性?

A: 可以通过以下方法提高全量恢复的可靠性:

  1. 定期验证备份文件的完整性
  2. 实施3-2-1备份原则
  3. 定期测试恢复流程
  4. 文档化恢复过程
  5. 培训相关人员

版本差异

SQLServer版本全量恢复特性差异
2008 R2基本全量恢复功能
2012引入Columnstore索引恢复支持
2014改进恢复性能
2016支持压缩备份恢复
2017支持直接从Azure Blob Storage恢复
2019引入加速数据库恢复(ADR)
2022改进ADR性能,支持从S3兼容存储恢复
2024增强恢复可靠性,支持更多恢复场景

总结

全量恢复是SQLServer恢复操作的基础,它使用完整备份将数据库恢复到完整备份完成时的状态。全量恢复适用于多种场景,如数据库完全损坏、创建测试环境和数据库迁移等。在实施全量恢复时,需要遵循最佳实践,包括恢复前准备、恢复过程中的监控和恢复后的验证。通过合理的恢复策略和优化措施,可以提高全量恢复的速度和可靠性,确保在发生数据丢失或系统故障时,能够快速、可靠地恢复数据,满足业务的RTO和RPO要求。