修復發生“由於數據移動,未能繼續以 NOLOCK 方式掃描”錯誤的數據庫


最近在系統運行中發現了一個錯誤,錯誤信息如下:
錯誤信息:查詢A201412C20568單證信息錯誤 ---> System.Data.OleDb.OleDbException: 由於數據移動,未能繼續以 NOLOCK 方式掃描。

一開始我認為企業的數據庫是SQL SERVER 2005以上的版本,使用了以下方式:
USE MASTER GO
 
 
ALTER DATABASE work_yf SET SINGLE_USER GO --允許丟失數據修復 DBCC CHECKDB (work_yf, REPAIR_ALLOW_DATA_LOSS) GO
 
ALTER DATABASE work_yf SET MULTI_USER 

在執行了命令之后,發現無法成功。后研究了一下企業使用的數據庫,發現是SQL SERVER 2000的。所以只能使用以下方式進行修復。

 

第一步:通過以下代碼查詢,是哪些表中出錯了

DECLARE @table_name sysname DECLARE ROY_table CURSOR FOR
SELECT name FROM sysobjects where xtype  in ('u','s') OPEN ROY_table FETCH NEXT FROM ROY_table INTO @table_name
WHILE @@FETCH_STATUS = 0 
BEGIN
DBCC CheckTable (@table_name) PRINT '--------------數據表'+@table_name + '的檢查整理完成------------------'

FETCH NEXT FROM ROY_table INTO @table_name
END
CLOSE ROY_table DEALLOCATE ROY_table

 

執行上述命名之后,會在“消息”窗口中顯示如下信息:(以下信息中只有出錯信息,其他正常信息已經去除)

服務器: 消息 8929,級別 16,狀態 1,行 10 對象 ID 2: 在文本 ID 177078272 中發現錯誤,該文本的所有者是由 RID = (1:135:19) id = 661577395 and indid = 3 標識的數據記錄。 服務器: 消息 8961,級別 16,狀態 1,行 10 表錯誤: 對象 ID 2。text、ntext 或 image 節點(位於頁 (1:66),槽 2,文本 ID 177078272)與該節點位於頁 (1:284),
槽 6 處的引用不匹配。 'sysindexes' 的 DBCC 結果。 對象 'sysindexes' 有 304 行,這些行位於 14 頁中。 CHECKTABLE 發現了 0 個分配錯誤和 2 個一致性錯誤(在表 'sysindexes' 中,該表的對象 ID 為 2)。 通過上面的提示信息,找到出錯的索引或統計信息
--------------數據表sysindexes的檢查整理完成------------------ 服務器: 消息 8936,級別 16,狀態 1,行 10 表錯誤: 對象 ID 709577566,索引 ID 1。B 樹鏈的鏈接不匹配。(1:2203)->next = (1:176),但 (1:176)->Prev = (1:2045)。 服務器: 消息 8977,級別 16,狀態 1,行 10 表錯誤: 對象 ID 709577566,索引 ID 1。未遇到頁 (1:2203) 的父節點。 'PDE_LIST_ORG' 的 DBCC 結果。 對象 'PDE_LIST_ORG' 有 216 行,這些行位於 11 頁中。 CHECKTABLE 發現了 0 個分配錯誤和 2 個一致性錯誤(在表 'PDE_LIST_ORG' 中,該表的對象 ID 為 709577566)。 repair_rebuild 是最低的修復級別(對於由 DBCC CHECKTABLE (work_yf.dbo.PDE_LIST_ORG ) 發現的錯誤而言)。 --------------數據表PDE_LIST_ORG的檢查整理完成------------------ 服務器: 消息 8978,級別 16,狀態 1,行 10 表錯誤: 對象 ID 725577623,索引 ID 1。頁 (1:3891) 缺少上一頁 (1:3892) 對它的引用。可能是因為鏈的鏈接有問題。 服務器: 消息 8976,級別 16,狀態 1,行 10 表錯誤: 對象 ID 725577623,索引 ID 1。在掃描操作中未發現頁 (1:3892),而其父代 (1:2198) 和上一頁 (1:3889) 指向了該頁。
請檢查先前的錯誤。 'PDE_LIST_ORG_HISTROY' 的 DBCC 結果。 對象 'PDE_LIST_ORG_HISTROY' 有 16755 行,這些行位於 489 頁中。 CHECKTABLE 發現了 0 個分配錯誤和 2 個一致性錯誤(在表 'PDE_LIST_ORG_HISTROY' 中,該表的對象 ID 為 725577623)。 repair_rebuild 是最低的修復級別(對於由 DBCC CHECKTABLE (work_yf.dbo.PDE_LIST_ORG_HISTROY ) 發現的錯誤而言)。 --------------數據表PDE_LIST_ORG_HISTROY的檢查整理完成------------------ 第二步,進行分析,除了上面的斜體字部分,需要注意,其他都很清楚,就是兩張業務表發生了錯誤。 而斜體字部分是指一張系統表sysindexes,需要進一步查詢是哪些索引出錯了。 1) 使用以下語句檢查是哪些索引出現了問題,原來是_WA_Sys_STATUS_276EDEB3出錯是問題。
SELECT *  FROM SYSINDEXES WHERE  id = 661577395 and indid = 3 
select * from sysobjects where id = 661577395
 第三步,進行修得操作。具體操作方法如下:
 --方法如下:
--1. 先停掉數據庫服務器,把出問題的數據庫(例如:work_yf)的.mdf與.ldf文件備份到備份目錄中。
--2.我們使用默認方式建立一個供恢復使用的數據庫(如work_yf)。可以在SQL   Server   Enterprise   Manager里面建立。  
--3.停掉數據庫服務器。  
--4.將剛才生成的數據庫的日志文件work_yf_log.ldf刪除,用要修復的數據庫mdf文件覆蓋剛才生成的數據庫數據文件work_yf_data.mdf。  
--5.啟動數據庫服務器。此時會看到數據庫work_yf的狀態為“置疑”。這時候不能對此數據庫進行任何操作。  
--6.設置數據庫允許直接操作系統表。此操作可以在SQL   Server   Enterprise   Manager里面選擇數據庫服務器,按右鍵,選擇“屬性”,
在“服務器設置”頁面中將“允許對系統目錄直接修改”一項選中。也可以使用如下語句來實現。  
use   master  
go  
exec sp_configure   'allow updates',1  
go    
reconfigure   with   override  
go  
 
         
         
        

--7.設置work_yf為緊急修復模式  
update sysdatabases set status=-32768 where dbid=DB_ID('work_yf')  
 
        

--此時可以在SQL   Server   Enterprise   Manager里面看到該數據庫處於“只讀\置疑\脫機\緊急模式”可以看到數據庫里面的表,
但是僅僅有系統表   --8.下面執行真正的恢復操作,重建數據庫日志文件  
go

dbcc rebuild_log('work_yf','D:\Program Files\Microsoft SQL Server\MSSQL\Data\work_yf_log.ldf')  

go
 
        

--執行過程中,如果遇到下列提示信息:  
--服務器:   消息   5030,級別   16,狀態   1,行   1  
--未能排它地鎖定數據庫以執行該操作。  
--DBCC   執行完畢。如果   DBCC   輸出了錯誤信息,請與系統管理員聯系。  
--說明您的其他程序正在使用該數據庫,如果剛才您在F步驟中使用SQL   Server   Enterprise   Manager打開了work_yf庫的系統表,
那么退出SQL   Server   Enterprise   Manager就可以了。   --正確執行完成的提示應該類似於:   --警告:   數據庫   'work_yf'   的日志已重建。已失去事務的一致性。應運行   DBCC   CHECKDB   以驗證物理一致性。
將必須重置數據庫選項,並且可能需要刪除多余的日志文件。   --DBCC   執行完畢。如果   DBCC   輸出了錯誤信息,請與系統管理員聯系。   --此時打開在SQL   Server   Enterprise   Manager里面會看到數據庫的狀態為“只供DBO使用”。此時可以訪問數據庫里面的用戶表了。   --9 設置為單用戶狀態
go

exec sp_dboption 'work_yf','dbo use only','false'  
GO

exec sp_dboption 'work_yf', 'single user', 'true'
go    
reconfigure   with   override  
 
        


--10 修復表,具體要修復哪些表,請在執行DBCC CheckTable (表名) ,自行檢查。我在這里使用了"重建索引並修復(REPAIR_REBUILD)"的選項。
一共有三個選項:

--1) 快速修復 REPAIR_FAST --2) 重建索引並修復 REPAIR_REBUILD --3) 允許丟失數據修復 REPAIR_ALLOW_DATA_LOSS
use work_yf
GO
DBCC CheckTable (PDE_LIST_ORG_HISTROY,REPAIR_REBUILD)
GO
DBCC CheckTable (PDE_LIST_ORG,REPAIR_REBUILD)
GO
DBCC CheckTable (PDE_HEAD,REPAIR_REBUILD)
 
        

--剛才我在檢查的時候,發現一個_WA_Sys_STATUS_276EDEB3也出錯了,這是SQL SERVER自動建立的統計信息,
所以需要進行刪除,然后在進行修復
GO
DROP STATISTICS PDE_HEAD._WA_Sys_STATUS_276EDEB3
GO
DBCC CheckTable (SYSINDEXES,REPAIR_REBUILD)
GO
 
        

--11.驗證數據庫一致性(可省略)  
 use   master  
 go   
DBCC CheckDB (work_yf) 
go
 
        

--一般執行結果如下:  
--CHECKDB   發現了   0   個分配錯誤和   0   個一致性錯誤(在數據庫   'work_yf'   中)。  
--DBCC   執行完畢。如果   DBCC   輸出了錯誤信息,請與系統管理員聯系。  


--12.設置數據庫為正常狀態  
exec sp_dboption 'work_yf', 'single user', 'false'
go
exec sp_dboption 'work_yf','dbo use only','false'  
go
 
        

--如果沒有出錯,那么恭喜,現在就可以正常的使用恢復后的數據庫啦。  
--13.最后一步,我們要將步驟E中設置的“允許對系統目錄直接修改”一項恢復。因為平時直接操作系統表是一件比較危險的事情。
當然,我們可以在SQL   Server   Enterprise   Manager里面恢復,也可以使用如下語句完成  
exec sp_configure   'allow updates',0  
go    
reconfigure   with   override  
go 
 
        

 

 
        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM