徵狀
當您在 Microsoft SQL Server 2008、SQL Server 2012、SQL Server 2008 R2 或 SQL Server 2014 的表格中,同時執行複雜的 UPDATE 語句與 NOLOCK 提示時,可能會發生非聚簇索引損毀。 此外,SQL Server 錯誤記錄中可能會記錄下列錯誤訊息:
<日期><時間> spid # 錯誤:8646、嚴重性:21、State: 1. <日期><時間> spid # 在資料庫 ' <DatabaseName>」中,找不到 table 2102402659 的索引 ID 3 中的索引項目。 指定的索引已損毀,或目前的更新方案有問題。 執行 DBCC CHECKDB 或 DBCC CHECKTABLE。 如果問題持續發生,請聯絡產品支援。 <日期><時間> spid # 使用 "dbghelp" 版本 "4.0.5" <日期><> spid # * * 轉儲執行緒-Spid = 0,EC = 0x0000000BD70624C0<Date><時間> spid # * * * 堆疊轉儲傳送至 Y:\MSSQL\MSSQL10。MSSQLSERVER\MSSQL\LOG\SQLDump0003.txt><2 日期><時間> spid # * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * <日期><時間> spid # * <日期><時間> spid # * 開始堆疊轉儲: <日期>< spid # *> 日期<時間><spid #> 日期 <時間><spid # *> 日期 <時間><spid # * CPerIndexMetaQS:: ErrorAbort-索引損壞><0 日期><時間> spid # *
注意您可以將 NOLOCK 提示套用至語句中的來源資料表。 不過,您無法將 NOLOCK 提示套用至語句中的目標資料表。
原因
之所以會發生這個問題,是因為當查詢多次讀取相同的值時, NOLOCK 提示會導致查詢不正確地讀取資料表中的值。
解決方案
此問題最初是在 SQL Server 的後續累積更新中修正。
SQL Server 2014 的累積更新1 /en-us/help/2931693
SQL Server 2012 累計更新11 /en-us/help/2908007
SQL Server 2012 SP1 的累積更新7 /en-us/help/2894115
SQL Server 2008 SP3 的累積更新13 /en-us/help/2880350
SQL Server 2008 R2 SP2 累積更新9 /en-us/help/2887606
每個新的 SQL Server 累計更新都包含所有的修正程式,以及前一個累積更新中所包含的所有安全性修正程式。 查看 SQL Server 的最新累計更新:
狀態
Microsoft 已確認<適用於>一節所列的 Microsoft 產品確實有上述問題。