【SQL Server备份恢复】提高恢复速度:通过数据库完整备份,来恢复损坏的某个页面
2014-03-04 13:57
447 查看
如果数据库比较大,而只是某个数据页损坏了,那么并不需要恢复整个数据库,而只需要通过完整备份,来修复损坏的数据页就可以了,另外,应用后续的日志就可以完全恢复的这个数据页的数据。
测试环境为:SQL Server 2008R2
如果是其他的数据库版本,可能会导致下面的部分代码不能运行。
1、创建一个包含主文件组、读写文件组的测试数据库
2、创建表,插入数据
3、完整备份
4、再次插入数据
5、日志备份
6、通过未记载的命令:dbcc writepage来模拟损坏数据页的数据
请不要在生成环境中使用dbcc writepage,因为这个命令可能会导致数据的严重损坏。
dbcc writepage的语法为:
dbcc writepage
({ dbid,'dbname' }, fileid, pageid, offset, length, data)
另外,通过如下的语句,可以查询出需要的修改的数据页,这个最后插入的一条v为0的数据,位于fileID=3,pageID=220,slot=215,这个%%lockres%%是sql server 2008才有的,可以用于返回数据所在的文件id,页id,记录id:
生成100个字节的错误数据:
模拟损坏数据:
7、检查数据库,会显示页3:220 的错误:
8、备份尾日志:
9、通过完整备份,修复数据页 3:220
10、还原日志
11、还原尾日志
12、验证数据是否恢复
测试环境为:SQL Server 2008R2
如果是其他的数据库版本,可能会导致下面的部分代码不能运行。
1、创建一个包含主文件组、读写文件组的测试数据库
use master go if DB_ID('db_test') is not null drop database db_test go CREATE DATABASE db_test ON ( NAME = db_test_DATA, FILENAME = 'c:\db_test.mdf' ), FILEGROUP FG_READ_WRITE ( NAME = db_test_RW, FILENAME = 'c:\db_test_RW.ndf' ) LOG ON ( NAME = db_test_LOG, FILENAME = 'c:\db_test.ldf' ) GO
2、创建表,插入数据
use db_test go create table xxx(v int,name varchar(100)) on FG_READ_WRITE insert into xxx select OBJECT_ID,name from sys.objects go /* 运行下面的插入数据,由于数据量很大,导致长时间运行. 所以,点了"取消执行查询"按钮. 但通过查询,发现log_reuse_wait_desc的状态为 active transaction: select name,log_reuse_wait_desc from sys.databases where name = 'db_test' 于是运行如下命令后,状态变为nothing,说明正常了: dbcc checkdb(db_test) */ insert into xxx select v,name from xxx go 10
3、完整备份
backup database db_test to disk ='c:\db_test.bak' with format /* 已为数据库 'db_test',文件 'db_test_DATA' (位于文件 1 上)处理了 184 页。 已为数据库 'db_test',文件 'db_test_RW' (位于文件 1 上)处理了 224 页。 已为数据库 'db_test',文件 'db_test_LOG' (位于文件 1 上)处理了 2 页。 BACKUP DATABASE 成功处理了 410 页,花费 0.525 秒(6.091 MB/秒)。 */
4、再次插入数据
insert into xxx select 0,'wc'
5、日志备份
backup log db_test to disk = 'c:\db_test.trn'
6、通过未记载的命令:dbcc writepage来模拟损坏数据页的数据
请不要在生成环境中使用dbcc writepage,因为这个命令可能会导致数据的严重损坏。
dbcc writepage的语法为:
dbcc writepage
({ dbid,'dbname' }, fileid, pageid, offset, length, data)
另外,通过如下的语句,可以查询出需要的修改的数据页,这个最后插入的一条v为0的数据,位于fileID=3,pageID=220,slot=215,这个%%lockres%%是sql server 2008才有的,可以用于返回数据所在的文件id,页id,记录id:
select %%lockres%% as 'RID' from xxx where v = 0 /* v name RID 0 wc 3:220:215 */
生成100个字节的错误数据:
select '0x'+REPLICATE('00',100)
模拟损坏数据:
dbcc writepage(db_test,3,220,20,100, 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ) /* 消息 8939,级别 16,状态 7,第 1 行 表错误: 对象 ID 68,索引 ID 1,分区 ID 281474981167104,分配单元 ID 72057594037927936 (类型为 LOB data),页 (0:0)。测试(m_freeData >= PageHeaderOverhead () && m_freeData <= (UINT)PAGESIZE - m_slotCnt * sizeof (Slot))失败。值为 0 和 8192。 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。 */
7、检查数据库,会显示页3:220 的错误:
use master go dbcc checkdb(db_test) /* 表错误: 对象 ID 0,索引 ID -1,分区 ID 0,分配单元 ID 72057594037927936 (类型为 Unknown),页 ID (3:220) 在其页头中包含错误的页 ID。页头中的 PageId = (0:0)。 CHECKDB 发现有 0 个分配错误和 1 个一致性错误与任何单个的对象都没有关联。 xxx的 DBCC 结果。 消息 8928,级别 16,状态 1,第 1 行 对象 ID 2105058535,索引 ID 0,分区 ID 72057594038779904,分配单元 ID 72057594039828480 (类型为 In-row data): 无法处理页 (3:220)。有关详细信息,请参阅其他错误消息。 对象 'xxx' 的 204 页中有 55081 行。 CHECKDB 在表 'xxx' (对象 ID 2105058535)中发现 0 个分配错误和 1 个一致性错误。 CHECKDB 在数据库 'db_test' 中发现 0 个分配错误和 2 个一致性错误。 对于由 DBCC CHECKDB (db_test)发现的错误,repair_allow_data_loss 是最低的修复级别。 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。 */
8、备份尾日志:
backup log db_test to disk = 'c:\db_test_trail.trn' with no_truncate /* 已为数据库 'db_test',文件 'db_test_LOG' (位于文件 1 上)处理了 6 页。 BACKUP LOG 成功处理了 6 页,花费 0.100 秒(0.434 MB/秒)。 */
9、通过完整备份,修复数据页 3:220
RESTORE DATABASE db_test page = N'3:220' FROM DISK = 'c:\db_test.bak' with norecovery /* 已为数据库 'db_test',文件 'db_test_RW' (位于文件 1 上)处理了 1 页。 RESTORE DATABASE ... FILE=<name> 成功处理了 1 页,花费 0.177 秒(0.044 MB/秒)。 */
10、还原日志
restore log db_test from disk = 'c:\db_test.trn' with norecovery /* 已为数据库 'db_test',文件 'db_test_RW' (位于文件 1 上)处理了 0 页。 已为数据库 'db_test',文件 'db_test_LOG' (位于文件 1 上)处理了 7 页。 RESTORE LOG 成功处理了 7 页,花费 0.092 秒(0.567 MB/秒)。 */
11、还原尾日志
restore log db_test from disk = 'c:\db_test_trail.trn' with recovery /* 已为数据库 'db_test',文件 'db_test_RW' (位于文件 1 上)处理了 0 页。 RESTORE LOG 成功处理了 0 页,花费 0.024 秒(0.000 MB/秒)。 */
12、验证数据是否恢复
--数据全部恢复 select * from xxx
相关文章推荐
- 【SQL Server备份恢复】提高恢复速度:通过数据库完整备份,来恢复损坏的某个页面
- 【SQL Server备份恢复】提高恢复速度:通过数据库完整备份,来恢复损坏的某个文件
- 【SQL Server备份恢复】提高恢复速度:通过数据库完整备份,来恢复损坏的某个文件
- SQL Server中通过扩展存储过程实现数据库的远程备份与恢复
- SQL Server如何提高数据库备份的速度
- SQL Server如何提高数据库备份的速度
- 【SQL Server备份恢复】提高备份速度
- SQL Server中通过扩展存储过程实现数据库的远程备份与恢复
- 【SQL Server备份恢复】提高SQL Server备份速度
- sql server中通过查询分析器实现数据库的备份与恢复方法分享
- Sql server 2008数据库误删的恢复(利用日志和一个完整备份)
- sql server中通过查询分析器实现数据库的备份与恢复方法分享
- 通过制定SQL计划和系统计划实现]SQL Server 2005数据库定期备份和删除历史备份记录
- 用WEB(ASP)方式实现SQL SERVER 数据库的备份和恢复
- SQL Server 2008数据库备份与恢复
- SQL Server 2005 & 2008 master与msdb数据库的备份与恢复
- 在SQL Server 2005和2008获取数据库备份或者恢复完成百分比
- 通过SQL Server 2008数据库复制实现数据库同步备份
- 通过SQL Server 2008数据库复制实现数据库同步备份
- 原来tfs2015崩溃或损坏, 利用原有tfs数据库备份恢复工作