use master go  alter database wc set single_user  with rollback immediate  drop database wc go  --1.创建数据库 create database wc on primary ( 	name = wc_data, 	filename = 'D:\wc_data.mdf' ) log on ( 	name = wc_log1, 	filename = 'd:\wc_log1.ldf'   ), ( 	name = wc_log2, 	filename = 'd:\wc_log2.ldf' )   --2.增加文件组 alter database wc add filegroup wc_fg1  alter database wc add filegroup wc_fg2  alter database wc add filegroup wc_fg3  alter database wc add filegroup wc_fg4  --3.把文件添加到文件组中 alter database wc add file ( 	name = wc_fg1_1, 	filename = 'd:\wc_fg1_1.ndf', 	size = 1MB ) to filegroup wc_fg1  alter database wc add file ( 	name = wc_fg2_1, 	filename = 'd:\wc_fg2_1.ndf', 	size = 1MB ) to filegroup wc_fg2  alter database wc add file ( 	name = wc_fg3_1, 	filename = 'd:\wc_fg3_1.ndf', 	size = 1MB ) to filegroup wc_fg3  alter database wc add file ( 	name = wc_fg4_1, 	filename = 'd:\wc_fg4_1.ndf', 	size = 1MB ) to filegroup wc_fg4  go  use wc go  --4.创建分区函数 create partition function wcLeftRange(datetime) as range left for values('2006-01-01','2007-01-01','2008-01-01')  create partition function wcRightRange(datetime) as range right for values('2006-01-01','2007-01-01','2008-01-01')   --5.创建分区方案 create partition scheme wcLeftRangeScheme as partition wcLeftRange to (wc_fg1,wc_fg2,wc_fg3,wc_fg4)   --6.创建分区表 create table dbo.wcT 	(wcId bigint not null, 	 wcV varchar(100) not null , 	 wcDate datetime not null, 	 constraint pk_wcid_date  	 primary key(wcId,wcDate) 	) on wcLeftRangeScheme(wcDate)   insert into dbo.wcT(wcId,wcV,wcDate) values(1,'2','2006-01-01 00:00:00'),       (2,'1','2005-12-31 23:59:59'),       (3,'2','2006-12-31 23:59:59'),       (4,'3','2007-01-01 00:00:00'),       (5,'4','2008-01-01 00:00:00'),       (6,'4','2008-12-31 23:59:59')   --7.显示每条数据所属分区号,从1开始计算 select *,         --$partition函数,后面是分区函数名称,列名称        $partition.wcLeftRange(wcDate) as partition  from wcT   create table T  ( id int primary key identity(1,1), v varchar(10)  ) on [primary]   insert into t values('b')

接下来备份数据库:

--备份数据库  backup database wc filegroup ='primary' to disk = 'd:\primary.bak'   backup database wc filegroup = 'wc_fg1' to disk = 'd:\wc_fg1.bak'  backup database wc filegroup = 'wc_fg2' to disk = 'd:\wc_fg2.bak'  backup database wc filegroup = 'wc_fg3' to disk = 'd:\wc_fg3.bak'  backup database wc filegroup = 'wc_fg4' to disk = 'd:\wc_fg4.bak'  backup log wc to disk ='d:\wc_log.trn'

 

下面,要模拟数据文件的损坏。

接下来,停止服务:net stop mssqlserver。

然后,把wc_fg1文件组所对应的文件:d:\wc_fg1_1.ndf 删掉。

重启服务:net  start  mssqlserver。

还原数据库,采用部分还原,使主文件组以及wc_fg1文件组,处于联机状态,这2个文件组的数据就可以访问:

/* 若要启动部分还原顺序,请使用 RESTORE 语句的 WITH PARTIAL 子句, 并提供一个备份集,其中至少包含主数据文件的完整副本。 不能出于任何其他目的使用 RESTORE 语句的 WITH PARTIAL 子句。 */ restore database wc filegroup ='primary' from disk = 'd:\primary.bak' with replace,      partial,      norecovery   restore database wc filegroup = 'wc_fg1' from disk = 'd:\wc_fg1.bak' with norecovery  restore log wc from disk ='d:\wc_log.trn'

 

查询T表、wcT表的数据:

--正常返回数据 select * from wc.dbo.t   --如果只查询第一个分区的数据,可以正常返回数据,不会报错 select *,         --$partition函数,后面是分区函数名称,列名称        $partition.wcLeftRange(wcDate) as partition  from wc.dbo.wcT where $partition.wcLeftRange(wcDate) =1   --如果查询第1、2个分区的数据,会报错 select *,         --$partition函数,后面是分区函数名称,列名称        $partition.wcLeftRange(wcDate) as partition  from wc.dbo.wcT where $partition.wcLeftRange(wcDate) in (1,2)   --继续恢复第二个文件组的数据 restore database wc filegroup = 'wc_fg2' from disk = 'd:\wc_fg2.bak' with norecovery  restore log wc from disk ='d:\wc_log.trn' with recovery  /* --备份尾部日志 backup log wc to disk = 'd:\wc_1.trn' with norecovery  --还原尾部日志 restore log wc from disk = 'd:\wc_1.trn' with recovery */  --不再报错,返回第1、2个分区的数据 select *,         --$partition函数,后面是分区函数名称,列名称        $partition.wcLeftRange(wcDate) as partition  from wc.dbo.wcT where $partition.wcLeftRange(wcDate) in (1,2)

1.通过上面的实验,说明了分区表的高可用性。

也就是如果还原了主文件组和第一个辅助文件组,那么这个分区表在第一个辅助文件组的数据,也就是第一个分区的数据,就可以访问,接下来可以继续恢复其他文件组。

 

2.还有一个问题是,如果是误删了分区表中第3个分区的数据,那么要如何才能恢复呢?

要想简单的通过直接还原第3个文件组的备份文件,来恢复是不可能的。

这个其实也是和上面的一样,通过部分还原,还原主文件组和第三个文件组,再把数据导出来,再导入原来的数据库就可以了,这样速度快多了。

 

3.另外,要恢复,必须要有日志备份,也就是在备份文件组后,必须要备份事务日志。

之所以要备份事务日志是因为,当备份主文件组后,在备份辅助文件组时,可能主文件组的数据会变化,这时如果不备份日志文件,会导致还原主文件组后,再还原辅助文件组时,就会有不一致,也就是说主文件组和辅助文件组,不完全是同一个时间点备份的,导致LSN不一致,这时通过之前备份的日志文件来还原,就可以使得整个数据处于一致状态。

 

 

下面更进一步,把分区表、文件组备份、差异备份、日志备份,部分还原、基于事务日志还原到特定时间点,相结合。

运用上面相同的建库脚本后,进行文件组的备份,和文件组的差异备份,事务日志的备份:

--文件组的备份 backup database wc filegroup ='primary' to disk = 'c:\primary.bak'  backup database wc filegroup = 'wc_fg1' to disk = 'c:\wc_fg1.bak'   --第1次删除数据 delete from wc.dbo.wcT   where wcid = 1  select GETDATE() --2013-09-07 14:16:36.910    --文件组的差异备份 backup database wc filegroup ='primary' to disk = 'c:\primary_diff.bak' with differential  backup database wc filegroup = 'wc_fg1' to disk = 'c:\wc_fg1_diff.bak' with differential   --第二次删除数据 delete from wc.dbo.T delete from wc.dbo.wcT where wcId = 2  select GETDATE()  --2013-09-07 14:16:54.183    --日志备份 backup log wc to disk = 'c:\wc_log.trn'  select GETDATE()  --2013-09-07 14:17:18.853

进行还原:

--1.基于文件组备份,日志备份,还原到指定时间点:恢复到第1次删除数据之前 restore database wc filegroup ='primary' from disk = 'c:\primary.bak' with replace ,      partial,      norecovery  restore database wc filegroup = 'wc_fg1' from disk = 'c:\wc_fg1.bak' with norecovery   restore log wc from disk = 'c:\wc_log.trn' with recovery,      stopat = '2013-09-07 14:16:36'    select * from wc.dbo.wcT where $partition.wcLeftRange(wcDate) = 1  select *  from wc.dbo.T    --2.基于文件组备份,日志备份, --还原到指定时间点:恢复到第1次删除数据之后,第2次删除数据之前 restore database wc filegroup ='primary' from disk = 'c:\primary.bak' with replace ,      partial,      norecovery  restore database wc filegroup = 'wc_fg1' from disk = 'c:\wc_fg1.bak' with norecovery  restore log wc from disk = 'c:\wc_log.trn' with recovery,      stopat = '2013-09-07 14:16:37'   select * from wc.dbo.wcT where $partition.wcLeftRange(wcDate) = 1  select *  from wc.dbo.T    --3.基于文件组备份,差异备份,日志备份, --还原到指定时间点:恢复到第2次删除数据之后 restore database wc filegroup ='primary' from disk = 'c:\primary.bak' with replace ,      partial,      norecovery  restore database wc filegroup = 'wc_fg1' from disk = 'c:\wc_fg1.bak' with norecovery    restore database wc filegroup ='primary' from disk = 'c:\primary_diff.bak' with norecovery  restore database wc filegroup = 'wc_fg1' from disk = 'c:\wc_fg1_diff.bak' with norecovery   restore log wc from disk = 'c:\wc_log.trn' with recovery,      stopat = '2013-09-07 14:16:55'   select * from wc.dbo.wcT where $partition.wcLeftRange(wcDate) = 1  select *  from wc.dbo.T