超大数据库的备份和恢复问题:分区表、文件组备份、部分还原

时间:2022-04-26 08:02:04

原文: 超大数据库的备份和恢复问题:分区表、文件组备份、部分还原


   
  
  1. use master
  2. go
  3. alter database wc
  4. set single_user
  5. with rollback immediate
  6. drop database wc
  7. go
  8. --1.创建数据库
  9. create database wc
  10. on primary
  11. (
  12. name = wc_data,
  13. filename = ‘D:wc_data.mdf‘
  14. )
  15. log on
  16. (
  17. name = wc_log1,
  18. filename = ‘d:wc_log1.ldf‘
  19. ),
  20. (
  21. name = wc_log2,
  22. filename = ‘d:wc_log2.ldf‘
  23. )
  24. --2.增加文件组
  25. alter database wc
  26. add filegroup wc_fg1
  27. alter database wc
  28. add filegroup wc_fg2
  29. alter database wc
  30. add filegroup wc_fg3
  31. alter database wc
  32. add filegroup wc_fg4
  33. --3.把文件添加到文件组中
  34. alter database wc
  35. add file
  36. (
  37. name = wc_fg1_1,
  38. filename = ‘d:wc_fg1_1.ndf‘,
  39. size = 1MB
  40. )
  41. to filegroup wc_fg1
  42. alter database wc
  43. add file
  44. (
  45. name = wc_fg2_1,
  46. filename = ‘d:wc_fg2_1.ndf‘,
  47. size = 1MB
  48. )
  49. to filegroup wc_fg2
  50. alter database wc
  51. add file
  52. (
  53. name = wc_fg3_1,
  54. filename = ‘d:wc_fg3_1.ndf‘,
  55. size = 1MB
  56. )
  57. to filegroup wc_fg3
  58. alter database wc
  59. add file
  60. (
  61. name = wc_fg4_1,
  62. filename = ‘d:wc_fg4_1.ndf‘,
  63. size = 1MB
  64. )
  65. to filegroup wc_fg4
  66. go
  67. use wc
  68. go
  69. --4.创建分区函数
  70. create partition function wcLeftRange(datetime)
  71. as range left for values( ‘2006-01-01‘, ‘2007-01-01‘, ‘2008-01-01‘)
  72. create partition function wcRightRange(datetime)
  73. as range right for values( ‘2006-01-01‘, ‘2007-01-01‘, ‘2008-01-01‘)
  74. --5.创建分区方案
  75. create partition scheme wcLeftRangeScheme
  76. as partition wcLeftRange
  77. to (wc_fg1,wc_fg2,wc_fg3,wc_fg4)
  78. --6.创建分区表
  79. create table dbo.wcT
  80. (wcId bigint not null,
  81. wcV varchar( 100) not null ,
  82. wcDate datetime not null,
  83. constraint pk_wcid_date
  84. primary key(wcId,wcDate)
  85. )
  86. on wcLeftRangeScheme(wcDate)
  87. insert into dbo.wcT(wcId,wcV,wcDate)
  88. values( 1, ‘2‘, ‘2006-01-01 00:00:00‘),
  89. ( 2, ‘1‘, ‘2005-12-31 23:59:59‘),
  90. ( 3, ‘2‘, ‘2006-12-31 23:59:59‘),
  91. ( 4, ‘3‘, ‘2007-01-01 00:00:00‘),
  92. ( 5, ‘4‘, ‘2008-01-01 00:00:00‘),
  93. ( 6, ‘4‘, ‘2008-12-31 23:59:59‘)
  94. --7.显示每条数据所属分区号,从1开始计算
  95. select *,
  96. --$partition函数,后面是分区函数名称,列名称
  97. $partition.wcLeftRange(wcDate) as partition
  98. from wcT
  99. create table T
  100. (
  101. id int primary key identity( 1, 1),
  102. v varchar( 10)
  103. ) on [primary]
  104. insert into t
  105. values( ‘b‘)


接下来备份数据库:


   
  
  1. --备份数据库
  2. backup database wc
  3. filegroup = ‘primary‘
  4. to disk = ‘d:primary.bak‘
  5. backup database wc
  6. filegroup = ‘wc_fg1‘
  7. to disk = ‘d:wc_fg1.bak‘
  8. backup database wc
  9. filegroup = ‘wc_fg2‘
  10. to disk = ‘d:wc_fg2.bak‘
  11. backup database wc
  12. filegroup = ‘wc_fg3‘
  13. to disk = ‘d:wc_fg3.bak‘
  14. backup database wc
  15. filegroup = ‘wc_fg4‘
  16. to disk = ‘d:wc_fg4.bak‘
  17. backup log wc
  18. to disk = ‘d:wc_log.trn‘

 

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


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

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

重启服务:net  start  mssqlserver。


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


   
  
  1. /*
  2. 若要启动部分还原顺序,请使用 RESTORE 语句的 WITH PARTIAL 子句,
  3. 并提供一个备份集,其中至少包含主数据文件的完整副本。
  4. 不能出于任何其他目的使用 RESTORE 语句的 WITH PARTIAL 子句。
  5. */
  6. restore database wc
  7. filegroup = ‘primary‘
  8. from disk = ‘d:primary.bak‘
  9. with replace,
  10. partial,
  11. norecovery
  12. restore database wc
  13. filegroup = ‘wc_fg1‘
  14. from disk = ‘d:wc_fg1.bak‘
  15. with norecovery
  16. restore log wc
  17. from disk = ‘d:wc_log.trn‘

 

查询T表、wcT表的数据:


   
  
  1. --正常返回数据
  2. select *
  3. from wc.dbo.t
  4. --如果只查询第一个分区的数据,可以正常返回数据,不会报错
  5. select *,
  6. --$partition函数,后面是分区函数名称,列名称
  7. $partition.wcLeftRange(wcDate) as partition
  8. from wc.dbo.wcT
  9. where $partition.wcLeftRange(wcDate) = 1
  10. --如果查询第1、2个分区的数据,会报错
  11. select *,
  12. --$partition函数,后面是分区函数名称,列名称
  13. $partition.wcLeftRange(wcDate) as partition
  14. from wc.dbo.wcT
  15. where $partition.wcLeftRange(wcDate) in ( 1, 2)
  16. --继续恢复第二个文件组的数据
  17. restore database wc
  18. filegroup = ‘wc_fg2‘
  19. from disk = ‘d:wc_fg2.bak‘
  20. with norecovery
  21. restore log wc
  22. from disk = ‘d:wc_log.trn‘
  23. with recovery
  24. /*
  25. --备份尾部日志
  26. backup log wc
  27. to disk = ‘d:wc_1.trn‘
  28. with norecovery
  29. --还原尾部日志
  30. restore log wc
  31. from disk = ‘d:wc_1.trn‘
  32. with recovery
  33. */
  34. --不再报错,返回第1、2个分区的数据
  35. select *,
  36. --$partition函数,后面是分区函数名称,列名称
  37. $partition.wcLeftRange(wcDate) as partition
  38. from wc.dbo.wcT
  39. where $partition.wcLeftRange(wcDate) in ( 1, 2)


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

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

 

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

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

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

 

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

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

 

 

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

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


   
  
  1. --文件组的备份
  2. backup database wc
  3. filegroup = ‘primary‘
  4. to disk = ‘c:primary.bak‘
  5. backup database wc
  6. filegroup = ‘wc_fg1‘
  7. to disk = ‘c:wc_fg1.bak‘
  8. --第1次删除数据
  9. delete from wc.dbo.wcT
  10. where wcid = 1
  11. select GETDATE() --2013-09-07 14:16:36.910
  12. --文件组的差异备份
  13. backup database wc
  14. filegroup = ‘primary‘
  15. to disk = ‘c:primary_diff.bak‘
  16. with differential
  17. backup database wc
  18. filegroup = ‘wc_fg1‘
  19. to disk = ‘c:wc_fg1_diff.bak‘
  20. with differential
  21. --第二次删除数据
  22. delete from wc.dbo.T
  23. delete from wc.dbo.wcT where wcId = 2
  24. select GETDATE() --2013-09-07 14:16:54.183
  25. --日志备份
  26. backup log wc
  27. to disk = ‘c:wc_log.trn‘
  28. select GETDATE() --2013-09-07 14:17:18.853


进行还原:


   
  
  1. --1.基于文件组备份,日志备份,还原到指定时间点:恢复到第1次删除数据之前
  2. restore database wc
  3. filegroup = ‘primary‘
  4. from disk = ‘c:primary.bak‘
  5. with replace ,
  6. partial,
  7. norecovery
  8. restore database wc
  9. filegroup = ‘wc_fg1‘
  10. from disk = ‘c:wc_fg1.bak‘
  11. with norecovery
  12. restore log wc
  13. from disk = ‘c:wc_log.trn‘
  14. with recovery,
  15. stopat = ‘2013-09-07 14:16:36‘
  16. select * from wc.dbo.wcT
  17. where $partition.wcLeftRange(wcDate) = 1
  18. select *
  19. from wc.dbo.T
  20. --2.基于文件组备份,日志备份,
  21. --还原到指定时间点:恢复到第1次删除数据之后,第2次删除数据之前
  22. restore database wc
  23. filegroup = ‘primary‘
  24. from disk = ‘c:primary.bak‘
  25. with replace ,
  26. partial,
  27. norecovery
  28. restore database wc
  29. filegroup = ‘wc_fg1‘
  30. from disk = ‘c:wc_fg1.bak‘
  31. with norecovery
  32. restore log wc
  33. from disk = ‘c:wc_log.trn‘
  34. with recovery,
  35. stopat = ‘2013-09-07 14:16:37‘
  36. select * from wc.dbo.wcT
  37. where $partition.wcLeftRange(wcDate) = 1
  38. select *
  39. from wc.dbo.T
  40. --3.基于文件组备份,差异备份,日志备份,
  41. --还原到指定时间点:恢复到第2次删除数据之后
  42. restore database wc
  43. filegroup = ‘primary‘
  44. from disk = ‘c:primary.bak‘
  45. with replace ,
  46. partial,
  47. norecovery
  48. restore database wc
  49. filegroup = ‘wc_fg1‘
  50. from disk = ‘c:wc_fg1.bak‘
  51. with norecovery
  52. restore database wc
  53. filegroup = ‘primary‘
  54. from disk = ‘c:primary_diff.bak‘
  55. with norecovery
  56. restore database wc
  57. filegroup = ‘wc_fg1‘
  58. from disk = ‘c:wc_fg1_diff.bak‘
  59. with norecovery
  60. restore log wc
  61. from disk = ‘c:wc_log.trn‘
  62. with recovery,
  63. stopat = ‘2013-09-07 14:16:55‘
  64. select * from wc.dbo.wcT
  65. where $partition.wcLeftRange(wcDate) = 1
  66. select *
  67. from wc.dbo.T


 

 

超大数据库的备份和恢复问题:分区表、文件组备份、部分还原超大数据库的备份和恢复问题:分区表、文件组备份、部分还原 不想长大啊 发布了416 篇原创文章 · 获赞 135 · 访问量 94万 他的留言板 关注