转自:http://blog.51cto.com/lzf328/955852 三篇

一、创建错误数据库

以前看Pual写过很多数据恢复的文章,他很多的测试都是自己创建的Corrupt数据库,其实我们自己也可以。

DBCC CHECKDB MSDN:https://docs.microsoft.com/zh-cn/sql/t-sql/database-console-commands/dbcc-checkdb-transact-sql?view=sql-server-2017


ALTER DATABASE Corrupt2008DemoFatalCorruption SET EMERGENCY        ---将数据库状态改为紧急模式
ALTER DATABASE Corrupt2008DemoFatalCorruption SET SINGLE_USER        --将数据库改为单用户访问
DBCC CHECKDB(Corrupt2008DemoFatalCorruption,repair_allow_data_loss)   ---运行repair_allow_data_loss修复
DBCC CHECKDB withNO_INFOMSGS                          ---修复完成后运行DBCC CHECKDB确定没有问题
ALTER DATABASE Corrupt2008DemoFatalCorruption SET MULTI_USER        --将数据库更改为多用户访问
--通过备份文件还数据页
命令:---Corrupt.bak是在数据库损坏之前的备份 restore database corrupt page='1:78'fromdisk='d:\mssql\corrupt.bak'withnorecovery backup log corrupttodisk='d:\mssql\corrupt.trn' restore log corruptfromdisk='d:\mssql\corrupt.trn'withrecovery 页面还原用于修复隔离出来的损坏页。 还原和恢复少量页面的速度可能比还原一个文件更快,因此减少了还原操作中处于脱机状态的数据量。 还原页步骤: 1. 获取要还原的损坏页的页 ID。 2. 从包含页的完整数据库备份、文件备份或文件组备份开始进行页面还原。 在 RESTORE DATABASE 语句中,使用 PAGE 子句列出所有要还原的页的页 ID。 3. 应用最近的差异。 4. 应用后续日志备份。 5. 创建新的数据库日志备份,使其包含已还原页的最终 LSN,即最后还原的页脱机的时间点。 设置为顺序中首先还原的最终 LSN 是重做目标 LSN。包含该页的文件的联机前滚可以在重做目标 LSN 处停止。 6. 还原新的日志备份。 应用这个新的日志备份后,就完成了页面还原,可以开始使用页了。 SQL Server页级别的数据恢复

--1.最近的完整备份
BACKUP DATABASE DBName TO DISK = N'C:\Test.bak'
 
--2.发现错误页(可以人为破坏)
SELECT * FROM msdb.dbo.suspect_pages
 
--3.立即备份日志1
BACKUP LOG DBName TO
DISK = 'C:\Test_LOG1.bak'
WITH INIT
 
--3.用完整备份,还原数据损坏的页
USE Master
RESTORE DATABASE DBName
PAGE = '1:832'
FROM DISK = 'C:\Test.bak'
WITH NORECOVERY
 
--4.备份日志2
BACKUP LOG DBName TO
DISK = 'C:\Test_LOG2.bak'
WITH INIT
 
--5.还原日志1
RESTORE LOG DBName FROM
DISK = 'C:\Test_LOG1.bak'
WITH NORECOVERY
 
--6.还原日志2
RESTORE LOG DBName FROM
DISK = 'C:\Test_LOG2.bak'
WITH NORECOVERY
 
--7.还原数据库状态,大工告成
RESTORE DATABASE DBName WITH RECOVERY
 
/*
人为破坏数据页
1.查看表使用的数据页
DBCC IND(DBName, TableName, -1)
2.修改数据库访问模式
ALTER DATABASE DBName SET SINGLE_USER WITH ROLLBACK IMMEDIATE
3.破坏数据页(1是PageFID,832是PagePID)
DBCC WRITEPAGE(DBName, 1, 832, 0, 1, 0x41, 1)
4.修改数据库访问模式
ALTER DATABASE DBName SET MULTI_USER
*/

1. 创建数据库数据表插入数据:

use master

go

create databasecorrupt

use corrupt

go

create tabletest(IDint, namevarchar(10))

declare @int asint

set @int = 1

while @int <20

begin

insert intotestvalues(@int,'allentest')

set @int += 1

end

2. 使用DBCC IND查看Test表所在的PageID

dbcc ind(corrupt,test,1)

3. 用DBCC PAGE查看TEST表的内容:

dbcc traceon(3604,-1)

go

dbcc page(corrupt,1,55,1)

这里我们只修改Slot 1数据,偏移地址为78,转化为10进制为120.

所以当前Slot1的实际地址为:55*8192+120=450680

4. 停掉SQL Server用XVI32打开数据文件然后输入地址找到对应的数据(可以看到数据与Step3中看到的数据一致)。

5. 对数据进行修改保存关闭XVI32。

6. 重启SQL Server然后用DBCC PAGE看Page 55 Slot1内容(已经被更改)

7. DBCCCHECKDB检查数据库发现下面的错误:

dbcc checkdb withno_infomsgs

Msg8928, Level 16, State 1, Line 1

Object ID2105058535, index ID 0, partition ID 72057594038779904, alloc unit ID72057594039828480 (type In-row data): Page (1:55) could not be processed. See other errors for details.

Msg8939, Level 16, State 98, Line 1

Table error: ObjectID 2105058535, index ID 0, partition ID 72057594038779904, alloc unit ID72057594039828480 (type In-row data), page (1:55). Test (IS_OFF (BUF_IOERR,pBUF->bstat)) failed. Values are 12716041 and -4.

这样我们就创建了一个Corrupt的数据库,稍后我会花时间测试恢复(page restore/ dbcc checkdbrepair_allow_data_loss/rebuildSQL Server log),然后把测试步骤发出来.

如果你不想自己创建的话,也可以使用Paul提供的两个Corrupt数据库做测试。

二、页面还原

上文我们已经新建了Corrupt的数据库,今天我们就用页面还原修复损坏的页面。

首先我们允许DBCC CHECKDB查看损坏的页面ID:

DBCC CHECKDB withNO_INFOMSGS

Msg 8928, Level 16,State 1, Line 1

Object ID2105058535, index ID 0, partition ID 72057594038779904, alloc unit ID72057594039828480 (type In-row data): Page (1:78) could not be processed. See other errors for details.

Msg 8939, Level 16,State 98, Line 1

Table error: ObjectID 2105058535, index ID 0, partition ID 72057594038779904, alloc unit ID72057594039828480 (type In-row data), page (1:78). Test (IS_OFF (BUF_IOERR,pBUF->bstat)) failed. Values are 12716041 and -4.

repair_allow_data_loss is the minimumrepair level for the errors found by DBCC CHECKDB (corrupt).

建议的修复 是repair_allow_data_loss,但是如果用repair_allow_data_loss修复的话就会有数据损失,而且可能会造成数据一致性问题。SQL Server 2005之后提供了Page Restore,使用Page Restore我们可以直接修复这个损坏的页面。

命令:---Corrupt.bak是在数据库损坏之前的备份

restore database corrupt page='1:78'fromdisk='d:\mssql\corrupt.bak'withnorecovery

backup log corrupttodisk='d:\mssql\corrupt.trn'

restore log corruptfromdisk='d:\mssql\corrupt.trn'withrecovery

页面还原用于修复隔离出来的损坏页。 还原和恢复少量页面的速度可能比还原一个文件更快,因此减少了还原操作中处于脱机状态的数据量。

还原页步骤:

1. 获取要还原的损坏页的页 ID。

2. 从包含页的完整数据库备份、文件备份或文件组备份开始进行页面还原。 在 RESTORE DATABASE 语句中,使用 PAGE 子句列出所有要还原的页的页 ID。

3. 应用最近的差异。

4. 应用后续日志备份。

5. 创建新的数据库日志备份,使其包含已还原页的最终 LSN,即最后还原的页脱机的时间点。 设置为顺序中首先还原的最终 LSN 是重做目标 LSN。包含该页的文件的联机前滚可以在重做目标 LSN 处停止。

6. 还原新的日志备份。 应用这个新的日志备份后,就完成了页面还原,可以开始使用页了。

更多页面还原信息请参考:http://msdn.microsoft.com/zh-cn/library/ms175168.aspx

三、repair_allow_data_loss 页面修复

运行DBCC CHECKDB withNO_INFOMSGS发现下面的错误:

Table error: ObjectID 7, index ID 2, partition ID 562949953880064, alloc unit ID 562949953880064(type In-row data), page (1:54). Test ((m_type >= DATA_PAGE &&m_type <= UNDOFILE_HEADER_PAGE) || (m_type == UNKNOWN_PAGE && level== BASIC_HEADER)) failed. Values are 0 and 0.

Msg 8939, Level 16,State 5, Line 4

Table error: ObjectID 7, index ID 2, partition ID 562949953880064, alloc unit ID 562949953880064(type In-row data), page (1:54). Test (m_headerVersion == HEADER_7_0) failed.Values are 0 and 1.

Msg 8939, Level 16,State 6, Line 4

Table error: ObjectID 7, index ID 2, partition ID 562949953880064, alloc unit ID 562949953880064(type In-row data), page (1:54). Test ((m_type >= DATA_PAGE &&m_type <= UNDOFILE_HEADER_PAGE) || (m_type == UNKNOWN_PAGE && level== BASIC_HEADER)) failed. Values are 0 and 0.

repair_allow_data_loss is the minimum repairlevel for the errors found by DBCC CHECKDB (Corrupt2008DemoFatalCorruption).

最小的修复级别是repair_allow_data_loss

如果我们没有数据库备份,无法使用页面还原,那么我们就需要用repair_allow_data_loss来修复(会有数据损失,而且不一定所有的都是可以恢复的 参考:http://blog.csdn.net/smithliu328/article/details/7827147

下面我们就使用DBCC CHECKDH repair_allow_data_loss来修复损坏的数据库。

---将数据库状态改为紧急模式

ALTER DATABASE Corrupt2008DemoFatalCorruption SETEMERGENCY

GO

--将数据库改为单用户访问

ALTER DATABASE Corrupt2008DemoFatalCorruptionSETSINGLE_USER

GO

--运行repair_allow_data_loss修复

DBCC CHECKDB(Corrupt2008DemoFatalCorruption,repair_allow_data_loss)

Go

---修复完成后运行DBCC CHECKDB确定没有问题

DBCC CHECKDB withNO_INFOMSGS

Go

--将数据库更改为多用户访问

ALTER DATABASE Corrupt2008DemoFatalCorruptionSETMULTI_USER

如果建议的修复级别为REPAIR_REBUILD,您可以放心执行,不会有数据损失。这包括快速修复(如修复非聚集索引中缺少的行)以及更耗时的修复(如重新生成索引)。

注意事项:

仅将 REPAIR 选项作为最后手段使用。 若要修复错误,建议您通过备份进行还原。 修复操作不会考虑表本身或表之间可能存在的任何约束。如果指定的表与一个或多个约束有关,建议您在修复操作后运行 DBCC CHECKCONSTRAINTS。如果必须使用 REPAIR,则运行不带有修复选项的 DBCC CHECKDB 来查找要使用的修复级别。如果使用 REPAIR_ALLOW_DATA_LOSS 级别,则建议您在运行带有此选项的 DBCC CHECKDB 之前备份数据库。

(4.4)dbcc checkdb 数据页修复的更多相关文章

  1. DBCC CHECKDB用法 手工修复数据库

          快速修复 DBCC CHECKDB ('数据库名', REPAIR_FAST)      重建索引并修复 DBCC CHECKDB ('数据库名', REPAIR_REBUILD) 如果必 ...

  2. DBCC page 数据页 堆 底层数据分布大小计算

    1.行的总大小: Row_Size = Fixed_Data_Size + Variable_Data_Size + Null_Bitmap + 4(4是指行标题开销) 开销定义: Fixed_Dat ...

  3. 【生产问题】-dbcc checkdb报错-数据页故障

    更多操作参考:https://www.cnblogs.com/gered/p/9435282.html [生产问题]-dbcc checkdb报错-数据页故障 数据页故障,索引页故障 use db_t ...

  4. DBCC CHECKDB

    DBCC CHECKDB 算是管理员们最常用的命令也是必须要知道的命令了.定期的检查及问题的修复都是比较重要的!!下面介绍一下 DBCC CHECKDB 的一些基本用法. DBCC CHECKDB 完 ...

  5. 在SQL Server里如何进行数据页级别的恢复

    在SQL Server里如何进行页级别的恢复 关键词:数据页修复 在今天的文章里我想谈下每个DBA应该知道的一个重要话题:在SQL Server里如何进行页级别还原操作.假设在SQL Server里你 ...

  6. sql sever2008 R2 检测到索引可能已损坏。请运行 DBCC CHECKDB。

    1.设置成单用户状态 USE MASTER ALTER DATABASE DBNAME SET SINGLE_USER; GO --DBNAME为修复的数据库名 2.执行修复语句,检查和修复数据库及索 ...

  7. MS Sql Server 数据库或表修复(DBCC CHECKDB)

    MS Sql Server 提供了很多数据库修复的命令,当数据库质疑或是有的无法完成读取时可以尝试这些修复命令.  1. DBCC CHECKDB  重启服务器后,在没有进行任何操作的情况下,在SQL ...

  8. SQL Server 修复数据库 相关 脚本 之 DBCC CHECKDB 用法 来自同事分享

    DBCC CHECKDB 用法详解, 手工修复数据库 1. 快速修复 DBCC CHECKDB ('数据库名',REPAIR_FAST) 2.重建索引并修复 DBCC CHECKDB ('数据库名', ...

  9. SQL Server dbcc checkdb 修复

    默认dbcc checkdb 只做数据库的检测数据库是否完好.不会主动做数据库的修复,要修复数据库,需要数据库设单用模式. 1.repair_allow_data_loss  可能导致数据丢失. 2. ...

随机推荐

  1. 【Android】 给我一个Path,还你一个酷炫动画

    本篇文章已授权微信公众号 hongyangAndroid (鸿洋)独家公布 转载请标明出处: http://blog.csdn.net/zxt0601/article/details/53040506 ...

  2. Atitit.java jar hell解决方案-----Djava.ext.dirs in ide envi..

    Atitit.java jar hell解决方案-----Djava.ext.dirs in ide envi.. Atitit.java class flect solu jar hell use  ...

  3. C++注释规范

      1 源文件头部注释 列出:版权.作者.编写日期和描述. /************************************************* Copyright:bupt Auth ...

  4. SQL数据库 CRUD

    1.删除表 drop  table +表名 2.修改表 alter  table+表名+ add(添加)+列名+ int(类型) alter  table+表名+ drop(删除)+column(列) ...

  5. MVC4的缓存

    目录(?)[+] MVC3缓存之一:使用页面缓存 在MVC3中要如果要启用页面缓存,在页面对应的Action前面加上一个OutputCache属性即可. 我们建一个Demo来测试一下,在此Demo中, ...

  6. Javascript模块规范

    因为有了模块,就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.但是有一个前提,就是大家必须以同样的方式编写模块. 目前,通行的Javascript模块规范共有两种:CommonJS和AMD ...

  7. mySQL 开启事件存储过程

    怎样在Navicat中设置,是数据库按照记录中的日期更新状态字段 其实这个很常用,比如你网站里的某条记录的日期——比如说数据库中某条活动记录的审核日期字段已经过期,亦即当前时间已经超过审核日期,那么定 ...

  8. 把world转成html

    本来用php转的 效果不太理想 很不稳定 最后试了下java 效果不错 只记录java的方法好了 其实他们的原理都是一样的啊,都是用到了微软的com 首先是准备工作 下载(明确dll的版本是64位的还 ...

  9. Spring MVC生成RSS源

    下面的示例演示如何使用Spring Web MVC框架生成RSS源. 首先使用Eclipse IDE,并按照以下步骤使用Spring Web Framework开发基于动态表单的Web应用程序: 创建 ...

  10. eclipse 查看源代码

    文地址:http://blog.csdn.net/sushengmiyan/article/details/18798473 本文作者:sushengmiyan 我们在使用Eclipse的时候,经常是 ...