当试图通过指定行 ID (RID) 来从数据页检索行,因为所请求的 RID 数字比该页的最后一个 RID 大而失败时,发生该错误。如果损坏的非聚集索引的叶级页指向数据页上不正确的或不存在的 RID,则可能在正常处理中发生该错误。
如果此错误是在其他用户更新系统表(执行 DDL)时,在只读操作中在系统表上发生该错误,则很可能是暂时的 624 错误(而不是索引损坏)。若要确认索引没有损坏,请执行不带修复子句的 DBCC CHECKTABLE
恢复过程视错误发生的时间而定。如果问题仍然存在,则以下过程可能不足以清除索引损坏问题。在这种情况下,请与你的主要支持提供商联系。提供 DBCC CHECKTABLE(如果要调查可能的系统表损坏)或 DBCC CHECKDB 的输出以供查看。
如果错误是在正常处理过程中发生的
执行带有 REPAIR_REBUILD 子句的 DBCC CHECKTABLE。如果执行带有 REPAIR_REBUILD 子句的 DBCC CHECKTABLE 未更正问题,则除去并重新创建受影响的索引。
重要提示: 如果执行带有 REPAIR_REBUILD 子句的 DBCC CHECKDB 未更正索引问题,或不确定带有 REPAIR_REBUILD 子句的 DBCC CHECKDB 对数据有何影响,则与你的主要支持提供商联系。
索引未知,查询已知
解决此问题最快的方法是执行带有 REPAIR_REBUILD 子句的 DBCC CHECKDB。这会修复整个数据库中的任何索引损坏。如果因数据库太大而不想运行 DBCC CHECKDB,请使用以下说明找到要除去并重新创建的特定索引。
如果不知道哪个索引导致了问题但知道哪个查询遇到了问题,请遵照下列说明操作。如果您不知道索引或查询,请按照下一节“索引和查询均未知”中的说明操作。
通过读取遇到错误的查询的显示计划输出来确定应除去哪个索引。如果设置 SET SHOWPLAN_TEXT 为 ON、SET NOEXEC 为 ON,然后运行有问题的查询,则输出指出查询使用哪个非聚集索引访问有问题的表。
例如:
USE pubs GO SET SHOWPLAN_TEXT ON GO SET NOEXEC ON GO SELECT title FROM titles WHERE title 'Cooking' GO
下面是结果集:
StmtText----------------SET NOEXEC ON(1 行受影响)
StmtText----------------SELECT title FROM titles WHERE title 'Cooking' (1 行受影响)
StmtText-------------|--Index Seek(OBJECT:([pubs].[dbo].[titles].[titleind]), SEEK:([titles].[title] ;[@1]) ORDERED FORWARD) (1 行受影响)
再次设置 SET NOEXEC 为 OFF,SET SHOWPLAN_TEXT 为 OFF: SET NOEXEC OFF GO SET SHOWPLAN_TEXT OFF GO
删除并重新创建步骤 1 中标识的索引(本例中为 titleind)。
索引和查询均未知
如果索引和查询均未知,则重建表中的所有非聚集索引,如下所示:
当获得表名时查看使用 DBCC CHECKDB 创建的输出:
如果对象 ID 小于 100,则无法除去可重新创建索引。请不要继续步骤 2 或 3。必须从某个已知的干净备份还原数据库。
如果对象 ID 为 100 或更大,则继续进行步骤 2。
使用 sp_helpindex 列出表中的所有索引,然后使用下列方法之一重建所有非聚集索引:
除去并重新创建表中的每个非聚集索引。
如果表具有聚集索引,则除去并重新创建该索引。这使得所有非聚集索引自动重建。如果您的表较大,则可能没有进行此操作的空间。通常,可用的空间必须为表大小的 1.2 倍。
在重新创建了适当的索引之后,在表上运行 DBCC CHECKTABLE 以确认问题已解决。
名称 | 说明 | 默认值 |
已启用 | 启用或禁用工作流。 | 否 |
优先级 | 定义警报优先级。 | 1 |
严重性 | 定义警报严重性。 | 2 |
Target | Microsoft.SQLServer.2008.DBEngine | ||
Category | EventCollection | ||
Enabled | False | ||
Event_ID | 624 | ||
Event Source | $Target/Property[Type="SQL!Microsoft.SQLServer.DBEngine"]/ServiceName$ | ||
Alert Generate | True | ||
Alert Severity | Error | ||
Alert Priority | Normal | ||
Remotable | True | ||
Alert Message |
| ||
Event Log | Application | ||
Comment | Mom2008ID='{B490F74B-6850-44E0-AB8A-3E86B10D96F2}';MOM2008GroupID={467ECC75-C5DA-42BD-955C-A73BBB51AF74} |
ID | Module Type | TypeId | RunAs |
---|---|---|---|
_F6DA1507_12AF_11D3_AB21_00A0C98620CE_ | DataSource | Microsoft.Windows.EventProvider | Microsoft.SQLServer.SQLDefaultAccount |
GenerateAlert | WriteAction | System.Health.GenerateAlert | Default |
<Rule ID="Microsoft.SQLServer.2008.Could_not_retrieve_row_from_page_by_RID_because_the_requested_RID_has_a_higher_number_than_the_last_RID_on_the_page_1_5_Rule" Target="SQL2008Core!Microsoft.SQLServer.2008.DBEngine" Enabled="false" ConfirmDelivery="true" Remotable="true" Comment="Mom2008ID='{B490F74B-6850-44E0-AB8A-3E86B10D96F2}';MOM2008GroupID={467ECC75-C5DA-42BD-955C-A73BBB51AF74}">
<Category>EventCollection</Category>
<DataSources>
<DataSource ID="_F6DA1507_12AF_11D3_AB21_00A0C98620CE_" Comment="{F6DA1507-12AF-11D3-AB21-00A0C98620CE}" TypeID="Windows!Microsoft.Windows.EventProvider" RunAs="SQL!Microsoft.SQLServer.SQLDefaultAccount">
<ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
<LogName>Application</LogName>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>PublisherName</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>$Target/Property[Type="SQL!Microsoft.SQLServer.DBEngine"]/ServiceName$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>EventDisplayNumber</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>624</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</DataSource>
</DataSources>
<WriteActions>
<WriteAction ID="GenerateAlert" TypeID="SystemHealth!System.Health.GenerateAlert">
<Priority>1</Priority>
<Severity>2</Severity>
<AlertMessageId>$MPElement[Name="Microsoft.SQLServer.2008.Could_not_retrieve_row_from_page_by_RID_because_the_requested_RID_has_a_higher_number_than_the_last_RID_on_the_page_1_5_Rule.AlertMessage"]$</AlertMessageId>
<AlertParameters>
<AlertParameter1>$Data/EventDescription$</AlertParameter1>
</AlertParameters>
<Suppression>
<SuppressionValue/>
</Suppression>
</WriteAction>
</WriteActions>
</Rule>