【SQL Server备份恢复】提高恢复速度:通过数据库完整备份,来恢复损坏的某个页面

如果数据库比较大,而只是某个数据页损坏了,那么并不需要恢复整个数据库,而只需要通过完整备份,来修复损坏的数据页就可以了,另外,应用后续的日志就可以完全恢复的这个数据页的数据。


测试环境为: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,因为这个命令可能会导致数据的严重损坏。

  1. dbcc writepage的语法为:  
  2.   
  3. dbcc writepage   
  4. ({ 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值