無法透過 RID 從分頁中擷取資料列,因為所要求的 RID 其編號大於分頁上最後一個 RID 的編號:已被取代

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 (Rule)

Knowledge Base article:

摘要

嘗試透過指定資料列識別碼 (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 建立的輸出:

如果物件識別碼小於 100,則無法卸除並重新建立索引。請不要繼續執行步驟 2 或 3。您必須從未受影響的備份還原資料庫。

如果物件識別碼大於或等於 100,請繼續步驟 2。

使用 sp_helpindex 列出資料表上的所有索引,然後使用以下方法之一重新建立所有非叢集索引:

卸除並重新建立資料表上的各非叢集索引。

如果資料表有叢集索引,請卸除並重新建立索引。此操作將導致所有非叢集索引自動重新建立。如果資料表很大,可能沒有足夠空間來執行此操作。一般來說,需要有 1.2 倍的資料表空間可用。

重新建立適當索引後,在資料表上執行 DBCC CHECKTABLE,以確認問題已得到解決。

Element properties:

TargetMicrosoft.SQLServer.2008.DBEngine
CategoryEventCollection
EnabledFalse
Event_ID624
Event Source$Target/Property[Type="SQL!Microsoft.SQLServer.DBEngine"]/ServiceName$
Alert GenerateTrue
Alert SeverityError
Alert PriorityNormal
RemotableTrue
Alert Message
無法透過 RID 從分頁中擷取資料列,因為所要求的 RID 其編號大於分頁上最後一個 RID 的編號
{0}
Event LogApplication
CommentMom2008ID='{B490F74B-6850-44E0-AB8A-3E86B10D96F2}';MOM2008GroupID={467ECC75-C5DA-42BD-955C-A73BBB51AF74}

Member Modules:

ID Module Type TypeId RunAs 
_F6DA1507_12AF_11D3_AB21_00A0C98620CE_ DataSource Microsoft.Windows.EventProvider Microsoft.SQLServer.SQLDefaultAccount
GenerateAlert WriteAction System.Health.GenerateAlert Default

Source Code:

<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>