备份和还原SQL Server数据库文件组

meh*_*tfi 12 sql-server backup restore sql-server-2008-r2 sql-server-2012

我使用sql server并拥有一个巨大的数据库,在多个文件组中按日期分区.数据库文件组是PRIMARY, FG2010, FG2011, FG2012, FG2013, and FG2014,FG2010,FG2011,FG2012和FG2013是只读的.

现在,备份方案是:

每个星期五凌晨2点获得完整备份

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

我想将此方案更改为:

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

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

除星期五凌晨2点外,每天都会获得PRIMARY和FG2014的差异备份

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

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

我希望有以下恢复计划方案:

恢复数据库的完整备份.

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

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

问题2:我可以将此方案用于恢复计划吗?

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

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

小智 15

Q1.是的你可以.您还需要定期进行事务日志备份.

Q2.是的,这也适用于恢复策略,同样需要进行事务日志备份.

Q3.当您使用备份创建开发数据库时,我会坚持这一点.有一些选项,如日志传送,但我不会实现它们,以保持从生产更新开发数据库.

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

脚本将: -

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

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

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

C:\SQLServer\Data
C:\SQLServer\Logs
C:\SQLServer\Backups
Run Code Online (Sandbox Code Playgroud)

我使用的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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

在每个表中插入数据(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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

完整备份: -

USE [master];
GO

BACKUP DATABASE [FGRestoreTEST]
TO DISK = N'C:\SQLServer\Backups\FGRestoreTEST.BAK';
GO
Run Code Online (Sandbox Code Playgroud)

然后从完整备份创建一个开发数据库(这将用于恢复将在下一步采取的文件组备份): -

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
Run Code Online (Sandbox Code Playgroud)

备份每个文件组: -

--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
Run Code Online (Sandbox Code Playgroud)

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

USE [FGRestoreTEST];
GO

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

TRUNCATE TABLE [FG2014_TABLE];
GO
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

再次,修改数据: -

USE [FGRestoreTEST];
GO

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

INSERT INTO [FG2014_TABLE]
SELECT 1, 'NEW'
GO 300
Run Code Online (Sandbox Code Playgroud)

备份事务日志(在现实环境中你可能会有多个这样的日志,但出于演示目的,我只需要一个): -

USE [master];
GO

BACKUP LOG [FGRestoreTEST]
TO DISK = 'C:\SQLServer\Backups\FGRestoreTest_LogBackup.trn';
GO
Run Code Online (Sandbox Code Playgroud)

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

BACKUP LOG [FGRestoreTEST_Dev]
TO DISK = 'C:\SQLServer\Backups\FGRestoreTest_TailLogBackup.trn'
WITH NORECOVERY;
GO
Run Code Online (Sandbox Code Playgroud)

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

--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
Run Code Online (Sandbox Code Playgroud)

然后是差异备份: -

--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
Run Code Online (Sandbox Code Playgroud)

然后是事务日志备份: -

RESTORE LOG [FGRestoreTEST_Dev]
FROM DISK = 'C:\SQLServer\Backups\FGRestoreTest_LogBackup.trn'
WITH NORECOVERY;
GO
Run Code Online (Sandbox Code Playgroud)

最后,数据库可以恢复: -

RESTORE DATABASE [FGRestoreTest_DEV] WITH RECOVERY;
GO
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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