SQL Server 对数据库损坏的错误类型做了细化,在此对几个典型的错误作一下介绍。
“The operating systemreturned error %ls to SQL Server during a %S_MSGat offset %#016I64x in file '%ls'.” 例如: Msg 823, Level 24, State 3, Line 1 The operating system returned error 5(Access is denied.) to SQLServer during a write at offset 0x0000000000e000 in file 'FilePath\FileName'. 823错误代表SQLServer在向操作系统申请某个页面读写的时候遇到Windows读取或写入请求失败。Windows返回的错误代码和相应的文本会插入消息中。对于读取操作,SQL Server在报出823错误之前已经重试读取请求4次。 从错误产生的机制可以看出,823错误是发出一个页面读写请求时发生的,和读写的内容没有关系。所以823错误和SQLServer本身无关。通常是物理文件损坏导致此错误,但也可能是设备驱动程序导致的。如果某个数据文件上反复出现823错误,要不就是硬件设备出了问题,要不就是数据文件已经发生了非常严重的损坏。这个错误基本上意味着数据页里的有效数据已经丢失,一般DBCCCHECKDB很难修复。
“SQL Server detecteda logical consistency-based I/O error: %ls. It occurred during a %S_MSG of page %S_PGIDin database ID %d at offset %#016I64x in file '%ls'.” 例如: SQL Server detected a logical consistency-based I/O error: tornpage (expected signature: 0x0; actual signature: 0x4e0372a8). It occurredduring a read of page (1:0) in database ID 13 at offset 0000000000000000 infile 'S:\Microsoft SQL Server\MSSQL.1\MSSQL\Data\www71_global_Data.mdf'. 此错误表明Windows报告已从磁盘成功读取页,但SQL Server检测到页中存在逻辑错误。那么SQLServer会检测到哪些“逻辑错误”呢?常见的错误类型有以下几种。
Checksum
TornPage
ShortTransfer
Bad PageId
RestorePending
StaleRead 从上面的介绍可以看出,824虽然是一个“逻辑错误”,是SQLServer主动发现的数据损坏,但是损坏的来源,大都不是SQL Server自己。这里的错误,主要是由于预期的写入没有完全完成导致的。所以824错误的原因,基本上还是在I/O子系统。由于SQL Server的读写请求是发给Windows,再由Windows发给底层的磁盘系统的,所以问题有可能发生在Windows以下的每一层,例如磁盘驱动器存在故障、磁盘固件存在问题、设备驱动程序不正确等。可以负责任地说,SQLServer自己是不会导致824错误的。 由于824错误是发生在页面这一级的逻辑错误,所以很多时候DBCC CHECKDB能够修复。但是这种修复也仅仅是逻辑上的,页面里面存储的数据在824错误发生之前就已经丢失,SQL Server无法将它们修复回来。所以824错误基本也意味着部分数据丢失。
“Attempt to fetchlogical page %S_PGIDin database %d failed. It belongs to allocation unit %I64d not to %I64d.” 例如: Attempt to fetch logical page (1:584) in database 2 failed. Itbelongs to allocation unit 445237904015360 not to 72057594060079104. 605也是一个非常有名的数据库损坏错误。此错误通常表示指定数据库中的页或分配已损坏。SQLServer会在根据页链接或使用索引分配映射(IAM)读取属于表的页时,检测到此损坏。分配给表的所有页必须属于与该表相关联的分配单元之一。如果页眉中包含的分配单元ID不匹配与表相关联的分配单元ID,将引发此异常。错误消息中列出的第一个分配单元ID是页眉中显示的ID,而第二个分配单元值则是与表相关联的ID。 严重级别为21表示可能存在数据损坏。造成的原因包括损坏的页链、损坏的IAM或该对象的sys.objects目录视图中存在无效条目。这些错误通常由硬件或磁盘设备驱动程序故障而引起。 严重级别为12表示可能存在暂时性错误,即在缓存中出现错误,但不表示对磁盘上的数据造成破坏。暂时性的605错误可由以下条件引发: · 操作系统过早地通知SQL Server已完成某个I/O操作;尽管不存在实际的数据损坏,但显示错误消息。 · 运行带有优化器提示NOLOCK的查询,或将事务隔离级别设置为READ UNCOMMITTED。当使用NOLOCK或READ UNCOMMITTED的查询尝试读取被其他用户移走或更改的数据时,将发生605错误。若要验证是否为暂时性的605错误,可以稍后重新运行该查询。 通常,如果在数据访问期间发生该错误,但后续的DBCCCHECKDB操作在没有出错的情况下完成,则605错误可能是暂时的。 由于605这个错误意味着一些页面分配出了问题,所以也是一个非常严重的数据库损坏。一般用DBCC CHECKDB也很难修复。
其他
PFS页面头有损坏: invalid PFS_PAGEpage header values.Type is 0. Check type, alloc unit ID and page ID on the page.
系统表上的聚集索引页面上有损坏: with latch type SH. sysindexes failed. Msg 7985, Level 16, State 2, Server SUNART, Line 1System tablepre-checks: Object ID 4. Could not read and latch page (1:51) withlatch type SH. Checkstatement terminated due to unrepairable error.
某个字段的值不符合字段数据类型定义: index ID 0, partition ID 72057594038321152, alloc unit ID72057594042318848 (type "In-row data"). Column "c1" value is out ofrange for data type "datetime". Update column to a legal value.
元数据有损坏: row (class=0,object_id=2105058535,column_id=0,referenced_major_id=2089058478,referenced_ minor_id=0)in sys.sql_dependencies has amatching row (object_id=2089058478)in sys.objects (type=SN) that is invalid. 遇到这些错误,管理员需要用DBCCCHECKDB命令来检查和修复。有些错误是可以不丢数据就能修复的,有些是要丢数据才能修复物理层面错误的,有些是即使丢数据也没办法修复的。现在就来介绍CHECKDB的使用技巧。 (责任编辑:熊猫蜀黍) |