创建、分离、重新附加并修复一个置疑数据库

 

创建、分离、重新附加并修复一个置疑数据库


原文地址:

http://www.sqlskills.com/BLOGS/PAUL/post/TechEd-Demo-Creating-detaching-re-attaching-and-fixing-a-suspect-database.aspx

译者:

本文首先创建一个置疑数据库,然后作者用事实告诫世人:千万不要对一个置疑数据库分离再附加 。接着用“假载”( hack-attach )的方法将上面的数据库再次置疑,最后用将数据库置为紧急模式的方法来修复数据库。

译文:

自从多年前开博开始,我一直想讲述这个主题:如何重新附加一个已经分离了的置疑数据库。这是一个我常常在论坛上看到的情景:一个数据库置疑了,于是 DBA 试图分离后再附加,但是失败了。今年我为 TechEd 的课堂写了一个小 demo ,展示如何用十六进制编辑器创建一个置疑数据库。这将是一片很长的博文,但是我已经将明天去英国的行李整理好了,所以我还有点空闲时间。

创建一个置疑数据库

首先我将创建一个名为 DemoSuspent 的简单的数据库,里面创建一个表,并放一些数据。

USE MASTER
GO
CREATE DATABASE DemoSuspect
GO

USE DemoSuspect ;
GO

CREATE TABLE Employees ( FirstName VARCHAR ( 20 ), LastName VARCHAR ( 20 ), YearlyBonus INT );
GO
INSERT
INTO Employees VALUES ( 'Paul' , 'Randal' , 10000 );
INSERT INTO Employees VALUES ( 'Kimberly' , 'Tripp' , 10000 );
GO

现在我将在一个显式事务下进行一个更新,然后使用 CHECKPOINT 命令强迫数据写到硬盘上。我不小心将 Kimberly 的奖金删掉了。( Kimberly 好像是作者的妻子)。

-- Simulate an in-flight transaction
BEGIN TRAN ;
UPDATE Employees SET YearlyBonus = 0 WHERE LastName = 'Tripp' ;
GO

CHECKPOINT ;
GO

在另一个窗口上,我用下面的语句来模拟异常灾难:

SHUTDOWN WITH NOWAIT ;
GO

现在 SQL Server 关闭了,我将模拟对日志文件的造成一次 I/O 错误。我用一个十六进制编辑器来做——我选择的编辑器是非常流行且好用的、由 Christian Mass 开发的 XVI32 ,。我打开日志文件,将第一个部分用 0 填充,然后保存起来。截屏如下:

 

经过上面的修改,当我再次启动 SQL Server 时,它会对 DemoSuspect 数据库进行恢复,但是会失败。于是将数据库置为 SUSPENT 状态。

(译注:下面是具体的过程)

我重启 SQL Server ,试图进入 DemoSuspect 数据库。

USE DemoSuspect ;
GO

Msg 945, Level 14, State 2, Line 1
Database 'DemoSuspect' cannot be opened due to inaccessible files or insufficient memory or disk space. See the SQL Server errorlog for details.

现在来检查一下数据库的状态:

SELECT DATABASEPROPERTYEX ( 'DemoSuspect' , 'STATUS' ) AS 'Status' ;
GO

Status
--------
SUSPECT

此时,正确的步骤是恢复备份数据。如果没有备份,那么最好将数据库置为紧急( EMERGENCY )模式,然后尽可能多的从里面取出一些数据,或者运行紧急模式修复。

但是我准备试试分离在附加。

分离数据库

我用 sp_detach_db 来分离数据库。

EXEC sp_detach_db 'DemoSuspect' ;
GO

Msg 947, Level 16, State 1, Line 1
Error while closing database 'DemoSuspect'. Check for previous additional errors and retry the operation.

哈哈,起作用吗?

SELECT * FROM sys.databases WHERE NAME = 'DemoSuspect' ;
GO

没有答案,说明分离已经成功了。

重新附加数据库

我用 sp_attach_db 来附加数据库。

EXEC sp_attach_db @dbname = N 'DemoSuspect' ,  
   
@filename1 = N 'C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect.mdf' ,  
   @filename2
= N 'C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect_LOG.ldf' ;
GO

Msg 5172, Level 16, State 15, Line 1
The header for file 'C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect_LOG.ldf' is not a valid database file header. The PageAudit property is incorrect.

CREATE DATABASE…ATTACH_REBUILD_LOG 来附加如何?它应该为我建一个新的日志文件吧?:

CREATE DATABASE DemoSuspect ON
   ( NAME = DemoSuspect , FILENAME = N 'C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect.mdf' )
FOR ATTACH_REBUILD_LOG ;
GO

Msg 5172, Level 16, State 15, Line 1
The header for file 'C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect_LOG.ldf' is not a valid database file header. The PageAudit property is incorrect.
File activation failure. The physical file name "C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect_LOG.ldf" may be incorrect.
The log cannot be rebuilt because the database was not cleanly shut down.
Msg 1813, Level 16, State 2, Line 1
Could not open new database 'DemoSuspect'. CREATE DATABASE is aborted.

呵呵,数据库知道还有一个活动的事务。 ATTACH_REBUILD_LOG 命令只能在数据库清爽关闭且日志文件丢失时,才会建一个新的日志文件。如果我现在删除了日志文件并且试图用这个命令,我能欺骗它吗?我复制了数据文件和日志文件,然后删除远了的日志文件,试了试:

CREATE DATABASE DemoSuspect ON
   
( NAME = DemoSuspect , FILENAME = N 'C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect.mdf' )
FOR ATTACH_REBUILD_LOG ;
GO

File activation failure. The physical file name "C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect_LOG.ldf " may be incorrect.
The log cannot be rebuilt because the database was not cleanly shut down.
Msg 1813, Level 16, State 2, Line 1
Could not open new database 'DemoSuspect'. CREATE DATABASE is aborted.

没有成功。这个过程成功的希望本来不大,但是我们看到 SQL SERVER 更聪明了。

基本上,上面的问题是因为数据库没有被清爽地关闭,这样在附加时就不得不进行恢复进程。鉴于日志文件已经被损坏,所以恢复变成不可能完成的任务了。所以,永远不用分离一个置疑数据库。

现在要将数据库附加进 SQL SERVER 的唯一途径就是耍些小技巧:我将创建一个与已分离数据库有相同文件布局且大小尽可能接近的的“哑”数据库,然后我关闭 SQL SERVER ,将受损文件换进来,然后重启 SQL SERVER 。如果一切顺利的话,一个损坏了的置疑数据库又将附加成功了。(译注:为什么“又”?因为本文开始创建的就是一个受损的置疑数据库)

这个方法的最大的缺点是如果 SQL SERVER 实例使能即时文件初始化,而数据文件又太大,那么创建“哑”数据库将花很长时间。这意味着当文件创建时你的应用程序是脱机的。

(译注:下面是上面小技巧的实现。上面是理论,并没有实现。)

因为我在上面已经备份了受损的数据库文件了,现在需要删掉数据文件(译注:上面做分离 / 附加时已经删除了日志文件了)。在删除以前,你需要确保你已经拥有多个受损数据库文件的拷贝了,仅仅以防万一嘛。删除掉日志数据文件,我就可以创建我自己的“哑”数据库了。

CREATE DATABASE DemoSuspect
GO

如果你忘了先删除已存在的数据文件,那么你将会得到下面的错误:

Msg 1802, Level 16, State 4, Line 1
CREATE DATABASE failed. Some file names listed could not be created. Check related errors.
Msg 5170, Level 16, State 1, Line 1
Cannot create file 'C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/Data/DemoSuspect.mdf' because it already exists. Change the file path or the file name, and retry the operation.

OK ,删掉数据文件然后再重试。现在我需要检查一下我的“哑”数据库文件是否在那儿(我都有点成偏执狂了),关闭 SQL SERVER ,删掉“哑”数据库的文件,然后换进来受损的文件。我在换进来之前又再次了拷贝了受损文件,以防万一嘛。

重启 SQL SERVER 后,我可以检查数据库的状态了:

SELECT DATABASEPROPERTYEX ( 'DemoSuspect' , 'STATUS' ) AS 'Status' ;
GO

Status
--------
SUSPECT

哦,在经过关闭服务、又是删除文件又是拷贝文件之后,我又有了一个附加了的置疑数据库了。现在我可以真正地修复它了。

修复数据库

如果你没有任何备份,那么进入数据库的唯一途径就是使用紧急( EMERGENCY )模式。它虽然让你进入数据库但是你需要知道恢复过程并没有结束,因为数据库的内容是事务(可能结构也是)不一致的。我将选择在紧急模式下修改数据库,有关紧急模式下修改数据库的详情请见博文《CHECKDB From Every Angle: EMERGENCY mode repair - the very, very last resort 》。

ALTER DATABASE DemoSuspect SET EMERGENCY ;
GO
ALTER
DATABASE DemoSuspect SET SINGLE_USER ;
GO
DBCC
CHECKDB ( DemoSuspect , REPAIR_ALLOW_DATA_LOSS ) WITH NO_INFOMSGS , ALL_ERRORMSGS ;
GO

Msg 5172, Level 16, State 15, Line 1
The header for file 'C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/DATA/DemoSuspect_log.LDF' is not a valid database file header. The PageAudit property is incorrect.

File activation failure. The physical file name "C:/Program Files/Microsoft SQL Server/MSSQL.1/MSSQL/DATA/DemoSuspect_log.LDF" may be incorrect.
The log cannot be rebuilt because the database was not cleanly shut down.
The Service Broker in database "DemoSuspect" will be disabled because the Service Broker GUID in the database (9E879BFC-B742-4A69-AB14-4D6BD6F99E02) does not match the one in sys.databases (B4568D23-7018-40CF-B189-9C29DE697C09).
Warning: The log for database 'DemoSuspect' has been rebuilt. Transactional consistency has been lost. The RESTORE chain was broken, and the server no longer has context on the previous log files, so you will need to know what they were. You should run DBCC CHECKDB to validate physical consistency. The database has been put in dbo-only mode. When you are ready to make the database available for use, you will need to reset database options and delete any extra log files.

首先试着进行一次正规的 ATTRCH_REBUILD_LOG ,如果失败了, DBCC CHECKDB 便接管过来,它会试着用尽可能多的受损日志来进行恢复之后强制重建日志文件。然后它进行一次完整的修复,也许数据库里原来有一些问题,但是现在已经没有了,所以就没有错误信息输出了。

注意显示 Service Broker GUID 错误的那行。我是用了特殊的方法来重新附加数据库的,当我创建“哑”数据库时,系统会在 master.sys.databases 表中为 demoSuspect 数据库创建一个 Service Broker GUID 。当我换进来受损的数据库时,它的 GUID 和“哑”数据库的 GUID 是不同的——所以现在我不能使用 Service Broker 了。所有的一切都是因为对置疑数据库不是修复而是分离造成的。

那么现在数据是什么样子呢?

USE DemoSuspect ;
GO

SELECT * FROM Employees ;
GO

FirstName   LastName   YearlyBonus
----------  ---------  ------------
Paul        Randal     10000
Kimberly    Tripp      0

Kimberly 今年没有奖金了——她不会快乐的 。当然这有点假,但是这也显示出经过紧急模式修复后,日志受损时的活动事务并没有回滚。本文中,我是知道灾难发生时的情况的,但是如果有一个繁忙的有成百上千活动事务的 OLTP 系统将会怎样?最后的数据又将是什么呢?

总结

是的,你是可以将一个分离的置疑数据库恢复的,但是这一点都不漂亮而且你必须非常小心。最好的做法永远都是拥有一个完备的备份方案,这将使你能尽快的恢复数据库。如果你有一个置疑数据库并且又没有备份,那么使用紧急模式也可以存取或者修复数据库。

希望本文能对遇到同样困境的人有所帮助。

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: T3数据库置疑修复工具是一种用于修复T3数据库中存在疑似错误或损坏的工具。T3数据库是一种常用于存储大量数据的数据库系统,然而,在长期使用和维护的过程中,由于各种原因,数据库中可能会出现一些疑似错误或损坏的情况。 这些错误或损坏可能包括:数据丢失、数据不一致、数据冲突等。对于这些问题,T3数据库置疑修复工具可以通过一系列的算法和技术来定位和修复。 首先,T3数据库置疑修复工具会对数据库进行全面的扫描和检查,以找出可能存在问题的数据。然后,它会基于已有的数据恢复策略和规则,对这些数据进行分析和修复。例如,对于数据丢失的情况,工具会按照事务的日志记录或备份文件来恢复丢失的数据。对于数据不一致的情况,工具会检查数据之间的关系,并进行相应的修复操作。 在修复过程中,T3数据库置疑修复工具会尽可能地保证数据的完整性和一致性,同时尽量避免对正常数据的干扰。修复完成后,工具会生成修复报告,详细说明修复的结果和过程,供管理员参考和查看。 总之,T3数据库置疑修复工具是一种用于修复T3数据库中存在疑似错误或损坏的工具,它通过扫描、分析和修复的方式,恢复数据库的正常运行,确保数据的完整性和一致性。 ### 回答2: T3数据库置疑修复工具是一种专门用于修复和解决T3数据库中的置疑数据问题的工具。T3数据库是指一种被用于存储和管理海量数据的关系数据库系统。在T3数据库中,由于各种原因,有时会出现置疑数据的情况,即数据库中存在一些数据不一致或者存在冲突,需要进行修复和解决。 T3数据库置疑修复工具通过对数据库中的置疑数据进行分析和处理,能够帮助管理员和开发人员快速地找到问题所在,并提供相应的修复方案。该工具通常具有以下几个功能: 1. 数据分析:工具会对数据库中的置疑数据进行全面的分析和统计,包括数据冲突、数据不一致、数据缺失等问题。通过数据分析,可以快速定位到具体的问题,为后续的修复提供依据。 2. 数据修复:基于分析结果,工具会提供一些修复方案,例如数据合并、数据删除、数据恢复等。管理员可以根据实际情况选择合适的修复方案,并进行相应的操作,以解决数据库中的置疑数据问题。 3. 数据验证:修复完成后,工具会进行数据验证,确保修复操作的有效性和准确性。通过数据验证,可以保证数据库中的数据再次达到一致和完整的状态。 总的来说,T3数据库置疑修复工具是一种能够帮助管理员快速发现和解决数据库置疑数据问题的工具。它具有数据分析、数据修复和数据验证等功能,可以有效提高数据库的可靠性和稳定性。在数据库管理和维护过程中,使用这样的工具能够减少管理员的工作负担,提高工作效率,保障数据的安全和完整性。 ### 回答3: T3数据库置疑修复工具是一种广泛应用于数据库管理领域的工具,它主要用于修复和恢复T3数据库中出现的问题。 首先,这个工具可以帮助我们检测和修复数据库中的错误和损坏。在使用T3数据库时,有时候会出现一些意外情况导致数据库中的数据发生损坏或错误,比如硬件故障、操作失误等。这个工具可以通过分析数据库中的日志和错误信息,快速定位并修复这些问题,从而保证数据库的正常运行。 其次,T3数据库置疑修复工具还可以帮助我们恢复误删的数据。在日常的数据库操作中,有时候会误删一些重要的数据,这可能会对业务造成严重影响。这个工具可以通过备份文件或者日志来恢复误删的数据,将数据库恢复到误删之前的状态,减少数据损失。 此外,T3数据库置疑修复工具还可以帮助我们恢复由于系统故障或人为错误导致的数据库崩溃。当数据库崩溃时,数据可能会丢失或不一致,这将对业务连续性和数据完整性造成风险。使用这个工具可以通过数据库日志来进行恢复,保证数据的一致性和完整性。 总之,T3数据库置疑修复工具是一款功能强大的数据库管理工具,可以通过检测和修复错误、恢复误删数据以及恢复数据库崩溃等功能,保证数据库的正常运行和数据的完整性。它在数据库管理中具有重要的作用,对于维护和管理数据库具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值