转自: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. 转:ios应用崩溃日志揭秘

    http://www.raywenderlich.com/zh-hans/30818/ios应用崩溃日志揭秘

  2. Redis之最大内存置换策略

    0.前言 Redis默认最大内存大小是应用程序可访问的内存大小, 32位windows下是2GB, linux下是3GB. 64位下可以访问的内存为2^64字节, Redis提供了maxmemory字 ...

  3. Atitit. visual studio vs2003 vs2005 vs2008  VS2010 vs2012 vs2015新特性 新功能.doc

    Atitit. visual studio vs2003 vs2005 vs2008  VS2010 vs2012 vs2015新特性 新功能.doc 1.1. Visual Studio2 1.2. ...

  4. CCS调试教程

    包括CCS3.3和CCS5.5两个版本的调试教程. CCS3.3 3.3教程来自http://zhujlhome.blog.163.com/blog/static/205621092201261032 ...

  5. Android JNI和NDK学习(05)--JNI真机调试(转)

    本文转自: http://www.cnblogs.com/skywang12345/archive/2013/05/23/3094250.html 本文主要介绍如何将JNI导入到真机进行调试.下面以M ...

  6. 28. Search a 2D Matrix 【easy】

    28. Search a 2D Matrix [easy] Write an efficient algorithm that searches for a value in an mx n matr ...

  7. Hash索引和BTREE索引2

    索引是数据库中用来提高性能的最常用工具.所有MySql列类型都可以被索引.索引用于快速找出在某个列中有一特定值的行.如果不使用索引,MYSQL必须从第一条记录开始然后读完整个表直到找出相关的行.常用的 ...

  8. java & c sharp 的关联

    第一.java是真正的与平台无关,c sharp不是,他只是口头上的与平台无关,最后,却要靠别人来实现非微软平台的类库. 第二.java中的类名.class 和c#的 typeof(类名)或者getT ...

  9. Windows Server 2008 R2入门之用户管理

    一.用户账户概述: ”用户”是计算机的使用者在计算机系统中的身份映射,不同的用户身份拥有不同的权限,每个用户包含一个名称和一个密码: 在Windows中,每个用户帐户有一个唯一的安全标识符(Secur ...

  10. FreeBSD安装MySQL5.7.17

    [root@tuhooo /usr/ports/databases/mysql57-server]# make install===>  Installing for mysql57-serve ...