最近在系統運行中發現了一個錯誤,錯誤信息如下:錯誤信息:查詢A201412C20568單證信息錯誤 ---> System.Data.OleDb.OleDbException: 由于數據移動,未能繼續以 NOLOCK 方式掃描。一開始我認為企業的數據庫是SQL SERVER 2005以上的版本,使用了以下方式:
USE MASTERGO ALTER DATABASE work_yf SET SINGLE_USERGO --允許丟失數據修復DBCC CHECKDB (work_yf, REPAIR_ALLOW_DATA_LOSS)GO ALTER DATABASE work_yf SET MULTI_USER
在執行了命令之后,發現無法成功。后研究了一下企業使用的數據庫,發現是SQL SERVER 2000的。所以只能使用以下方式進行修復。
第一步:通過以下代碼查詢,是哪些表中出錯了
DECLARE @table_name sysnameDECLARE ROY_table CURSOR FORSELECT name FROM sysobjects where xtype in ('u','s')OPEN ROY_tableFETCH NEXT FROM ROY_table INTO @table_nameWHILE @@FETCH_STATUS = 0 BEGINDBCC CheckTable (@table_name)PRINT '--------------數據表'+@table_name + '的檢查整理完成------------------'FETCH NEXT FROM ROY_table INTO @table_nameENDCLOSE ROY_tableDEALLOCATE 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.下面執行真正的恢復操作,重建數據庫日志文件
godbcc 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 設置為單用戶狀態
goexec sp_dboption 'work_yf','dbo use only','false' GOexec 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_yfGODBCC CheckTable (PDE_LIST_ORG_HISTROY,REPAIR_REBUILD)GODBCC CheckTable (PDE_LIST_ORG,REPAIR_REBUILD)GODBCC CheckTable (PDE_HEAD,REPAIR_REBUILD)
--剛才我在檢查的時候,發現一個_WA_Sys_STATUS_276EDEB3也出錯了,這是SQL SERVER自動建立的統計信息,所以需要進行刪除,然后在進行修復
GODROP STATISTICS PDE_HEAD._WA_Sys_STATUS_276EDEB3GODBCC 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'goexec 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
新聞熱點
疑難解答