【问题标题】:Backup and restore SQL Server database filegroup备份和恢复 SQL Server 数据库文件组
【发布时间】:2014-09-15 06:12:52
【问题描述】:

我使用 sql server 并拥有一个庞大的数据库,该数据库按日期划分为多个文件组。 数据库文件组是PRIMARY, FG2010, FG2011, FG2012, FG2013, and FG2014,FG2010、FG2011、FG2012和FG2013是只读的。

现在,备份方案是:

每周五凌晨 2:00 获取完整备份

除周五外,每周的每一天都在凌晨 2:00 获取差异备份

我想把这个场景改成:

获取数据库的完整备份(一次)

在每周五凌晨 2:00 获取 PRIMARY 和 FG2014 的完整备份

除周五凌晨 2:00 外,每天都对 PRIMARY 和 FG2014 进行差异备份

问题 1:我可以有这种情况吗?

我也有一个恢复计划。每天我都会通过作业自动将备份文件复制到另一台服务器然后恢复它,以便有恢复测试计划并将恢复的数据库用于开发人员和测试人员用户。

我希望有以下恢复计划的场景:

恢复数据库的完整备份。

恢复 PRIMARY 和 FG2014 的上次完整备份。

恢复 PRIMARY 和 FG2014 的上次差异备份。

问题 2:我可以将这种情况纳入恢复计划吗?

问题 3:我可以有更好的备份和恢复方案吗?

请用 TSQL 查询回答我的问题。

【问题讨论】:

  • 我认为你可以避免每次只读文件时备份和恢复
  • 数据库的恢复模式是什么?我没有看到任何提及事务日志备份的内容,因此假设正在使用 SIMPLE,但鉴于恢复模型决定了可用的恢复方法,我将不胜感激。

标签: sql-server sql-server-2008-r2 sql-server-2012 backup restore


【解决方案1】:

第一季度。是的你可以。您还需要定期备份事务日志。

第二季度。是的,这也适用于恢复策略,同样您需要进行事务日志备份。

第三季度。当您使用备份来创建开发数据库时,我会坚持这一点。有诸如日志传送之类的选项,但我不会实施它们以保持开发数据库从生产中更新。

我已经编写了一些演示脚本,您可以使用它们来运行您在本地实例上建议的场景。

脚本将:-

  1. 创建一个包含多个文件组的测试数据库,其中一些是只读的。
  2. 从测试数据库的备份创建开发数据库。
  3. 对测试数据库进行文件组备份并通过开发数据库进行恢复

请查看并运行脚本。如果您有任何问题,请告诉我。

在使用脚本之前,请确保您的计算机上有以下文件路径:-

C:\SQLServer\Data
C:\SQLServer\Logs
C:\SQLServer\Backups

我使用的SQL Server版本是2012 SP2 CU2 Developer Edition。

首先创建测试数据库:-

CREATE DATABASE [FGRestoreTEST]
 ON  PRIMARY 
( NAME = N'FGRestoreTEST', FILENAME = N'C:\SQLServer\Data\FGRestoreTEST.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), 
 FILEGROUP [FG2010] 
( NAME = N'FG2010', FILENAME = N'C:\SQLServer\Data\FG2010.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), 
 FILEGROUP [FG2011] 
( NAME = N'FG2011', FILENAME = N'C:\SQLServer\Data\FG2011.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), 
 FILEGROUP [FG2012] 
( NAME = N'FG2012', FILENAME = N'C:\SQLServer\Data\FG2012.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), 
 FILEGROUP [FG2013] 
( NAME = N'FG2013', FILENAME = N'C:\SQLServer\Data\FG2013.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), 
 FILEGROUP [FG2014] 
( NAME = N'FG2014', FILENAME = N'C:\SQLServer\Data\FG2014.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON 
( NAME = N'FGRestoreTEST_log', FILENAME = N'C:\SQLServer\Logs\FGRestoreTEST_log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

然后在每个文件组中创建表:-

USE [FGRestoreTEST];
GO

CREATE TABLE [PRIMARY_TABLE]
(ID INT,
 NAME CHAR(4)) ON [PRIMARY];

CREATE TABLE [FG2010_TABLE]
(ID INT,
 NAME CHAR(4)) ON [FG2010];

 CREATE TABLE [FG2011_TABLE]
(ID INT,
 NAME CHAR(4)) ON [FG2011];

CREATE TABLE [FG2012_TABLE]
(ID INT,
 NAME CHAR(4)) ON [FG2012];

CREATE TABLE [FG2013_TABLE]
(ID INT,
 NAME CHAR(4)) ON [FG2013];

CREATE TABLE [FG2014_TABLE]
(ID INT,
 NAME CHAR(4)) ON [FG2014];
 GO

在每个表中插入数据(100 行):-

INSERT INTO [PRIMARY_TABLE]
SELECT 1, 'TEST'
GO 100

INSERT INTO [FG2010_TABLE]
SELECT 1, 'TEST'
GO 100

INSERT INTO [FG2011_TABLE]
SELECT 1, 'TEST'
GO 100

INSERT INTO [FG2012_TABLE]
SELECT 1, 'TEST'
GO 100

INSERT INTO [FG2013_TABLE]
SELECT 1, 'TEST'
GO 100

INSERT INTO [FG2014_TABLE]
SELECT 1, 'TEST'
GO 100

然后将某些文件组设置为只读:-

ALTER DATABASE [FGRestoreTEST]
MODIFY FILEGROUP [FG2010] READ_ONLY;

ALTER DATABASE [FGRestoreTEST]
MODIFY FILEGROUP [FG2011] READ_ONLY;

ALTER DATABASE [FGRestoreTEST]
MODIFY FILEGROUP [FG2012] READ_ONLY;

ALTER DATABASE [FGRestoreTEST]
MODIFY FILEGROUP [FG2013] READ_ONLY;
GO

进行完整备份:-

USE [master];
GO

BACKUP DATABASE [FGRestoreTEST]
TO DISK = N'C:\SQLServer\Backups\FGRestoreTEST.BAK';
GO

然后从完整备份创建一个开发数据库(这将用于恢复接下来将进行的文件组备份):-

RESTORE DATABASE [FGRestoreTEST_Dev]
FROM DISK = N'C:\SQLServer\Backups\FGRestoreTEST.BAK' WITH
MOVE 'FGRestoreTEST' TO 'C:\SQLServer\Data\FGRestoreTEST_Dev.mdf',
MOVE 'FG2010' TO 'C:\SQLServer\Data\FG2010_Dev.ndf',
MOVE 'FG2011' TO 'C:\SQLServer\Data\FG2011_Dev.ndf',
MOVE 'FG2012' TO 'C:\SQLServer\Data\FG2012_Dev.ndf',
MOVE 'FG2013' TO 'C:\SQLServer\Data\FG2013_Dev.ndf',
MOVE 'FG2014' TO 'C:\SQLServer\Data\FG2014_Dev.ndf',
MOVE 'FGRestoreTEST_log' TO 'C:\SQLServer\Logs\FGRestoreTEST_Dev_log.ldf',
RECOVERY,STATS=5;
GO

备份每个文件组:-

--http://msdn.microsoft.com/en-us/library/ms189906.aspx
BACKUP DATABASE [FGRestoreTEST]
   FILEGROUP = 'PRIMARY'
   TO DISK = 'C:\SQLServer\Backups\FGRestoreTEST_PRIMARY.bak';

BACKUP DATABASE [FGRestoreTEST]
   FILEGROUP = 'FG2010'
   TO DISK = 'C:\SQLServer\Backups\FGRestoreTEST_FG2010.bak';

BACKUP DATABASE [FGRestoreTEST]
   FILEGROUP = 'FG2011'
   TO DISK = 'C:\SQLServer\Backups\FGRestoreTEST_FG2011.bak';

BACKUP DATABASE [FGRestoreTEST]
   FILEGROUP = 'FG2012'
   TO DISK = 'C:\SQLServer\Backups\FGRestoreTEST_FG2012.bak';

BACKUP DATABASE [FGRestoreTEST]
   FILEGROUP = 'FG2013'
   TO DISK = 'C:\SQLServer\Backups\FGRestoreTEST_G2013.bak';

BACKUP DATABASE [FGRestoreTEST]
   FILEGROUP = 'FG2014'
   TO DISK = 'C:\SQLServer\Backups\FGRestoreTEST_FG2014.bak';
GO

现在我们将修改 Primary 和 FG2014 文件组中的数据:-

USE [FGRestoreTEST];
GO

INSERT INTO [PRIMARY_TABLE]
SELECT 1, 'TEST'
GO 100

TRUNCATE TABLE [FG2014_TABLE];
GO

对文件组进行差异备份:-

BACKUP DATABASE [FGRestoreTest]
   FILEGROUP = 'PRIMARY'
   TO DISK = 'C:\SQLServer\Backups\FGRestoreTest_PRIMARYDIFF.bak'
   WITH DIFFERENTIAL;

BACKUP DATABASE [FGRestoreTest]
   FILEGROUP = 'FG2014'
   TO DISK = 'C:\SQLServer\Backups\FGRestoreTest_FG2014DIFF.bak'
   WITH DIFFERENTIAL;
GO

再次修改数据:-

USE [FGRestoreTEST];
GO

INSERT INTO [PRIMARY_TABLE]
SELECT 1, 'TEST'
GO 100

INSERT INTO [FG2014_TABLE]
SELECT 1, 'NEW'
GO 300

备份事务日志(在现实生活环境中您可能会有不止一个,但出于演示目的,我只使用一个):-

USE [master];
GO

BACKUP LOG [FGRestoreTEST]
TO DISK = 'C:\SQLServer\Backups\FGRestoreTest_LogBackup.trn';
GO

好的,现在我们可以恢复开发数据库了。首先,我们进行 Tail Log 备份,将数据库置于恢复状态。注意:- 我们不会使用这个备份!

BACKUP LOG [FGRestoreTEST_Dev]
TO DISK = 'C:\SQLServer\Backups\FGRestoreTest_TailLogBackup.trn'
WITH NORECOVERY;
GO

现在我们可以恢复读写文件组的完整备份了:-

--http://msdn.microsoft.com/en-us/library/aa337540.aspx
--Restore primary filegroup
RESTORE DATABASE [FGRestoreTEST_Dev]
   FILEGROUP = 'PRIMARY'
   FROM DISK = 'C:\SQLServer\Backups\FGRestoreTEST_PRIMARY.bak'
   WITH NORECOVERY;
GO

--Restore FG2014 filegroup 
RESTORE DATABASE [FGRestoreTEST_Dev]
   FILEGROUP = 'FG2014'
   FROM DISK = 'C:\SQLServer\Backups\FGRestoreTEST_FG2014.bak'
   WITH NORECOVERY;
GO

然后是差异备份:-

--Restore PRIMARY differential backup
RESTORE DATABASE [FGRestoreTEST_Dev]
   FILEGROUP = 'PRIMARY'
   FROM DISK = 'C:\SQLServer\Backups\FGRestoreTest_PRIMARYDIFF.bak'
   WITH NORECOVERY;
GO

--Restore FG2014 differential backup
RESTORE DATABASE [FGRestoreTEST_Dev]
   FILEGROUP = 'FG2014'
   FROM DISK = 'C:\SQLServer\Backups\FGRestoreTest_FG2014DIFF.bak'
   WITH NORECOVERY;
GO

然后是事务日志备份:-

RESTORE LOG [FGRestoreTEST_Dev]
FROM DISK = 'C:\SQLServer\Backups\FGRestoreTest_LogBackup.trn'
WITH NORECOVERY;
GO

终于可以恢复数据库了:-

RESTORE DATABASE [FGRestoreTest_DEV] WITH RECOVERY;
GO

作为最后的测试,检查数据:-

USE [FGRestoreTEST_Dev];
GO

SELECT COUNT(*) AS [PRIMARY_TABLE]
FROM [PRIMARY_TABLE];

SELECT COUNT(*) AS [FG2010_TABLE]
FROM [FG2010_TABLE];

SELECT COUNT(*) AS [FG2011_TABLE]
FROM [FG2011_TABLE];

SELECT COUNT(*) AS [FG2012_TABLE]
FROM [FG2012_TABLE];

SELECT COUNT(*) AS [FG2013_TABLE]
FROM [FG2013_TABLE];

SELECT COUNT(*) AS [FG2014_TABLE]
FROM [FG2014_TABLE];

SELECT TOP (1) *
FROM [FG2014_TABLE];
GO

因此,根据所做的数据更改,我们希望在 PRIMARY 和 FG2014 文件组中看到 300 条记录,其余 100 条记录,并且 FG2014 中名称列中的所有值都设置为“新”。

【讨论】:

    【解决方案2】:

    A1: 是的,您可以有这种情况,但是,如果需要,备份策略不提供持续的方式来恢复 FG2010 到 2013 年,因为只有一次完整的数据库备份存在.

    A2:是的,有一些调整。您希望实现的称为分段还原,所需方法的大部分所需指令可在联机丛书示例中找到:Piecemeal Restore of Only Some Filegroups

    主要区别在于您将通过以前恢复的完整数据库备份进行恢复,而不是在特定文件组遇到问题的实时数据库上进行恢复。

    通过使用上述参考资料,您应该能够轻松快速地为您的需求创建测试用例/概念证明。如果您遇到困难,请将您的尝试/代码添加到问题中,这里的优秀社区小伙子将提供指导。通过您的一点努力和社区的一些指导,我相信您可以回答自己的问题。教人钓鱼之类的......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-16
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 2011-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多