對數據庫CacheDBMSIntl執行DBCC checkcatalog(‘CacheDBMSIntl’)時遇到報錯如下
Msg 3853, Level 16, State 1, Line 7
Attribute (object_id=1071830442) of row (object_id=1071830442,column_id=1) in sys.columns does not have a matching row (object_id=1071830442) in sys.objects.
Msg 3853, Level 16, State 1, Line 7
Attribute (object_id=1071830442) of row (object_id=1071830442,column_id=2) in sys.columns does not have a matching row (object_id=1071830442) in sys.objects.
...
Msg 3853, Level 16, State 1, Line 7
Attribute (object_id=1071830442) of row (object_id=1071830442,column_id=51) in sys.columns does not have a matching row (object_id=1071830442) in sys.objects.
這段報錯看起來是sys.columns中1到51個字段對應的表的object_id=1071830442和sys.objects對應的表的object_id匹配不是,使用如下兩個語句查詢這個兩個系統視圖,發現果然如此,sys.objects沒有該表的記錄,但是sys.columns有該表的記錄,說明系統視圖sys.objects和sys.columns信息對應不上,按正常邏輯只要是執行drop table這張操作是會同時在這兩個系統視圖刪除這表的信息,而且Sqlserver從Sqlserver 2005之后就不能再對系統視圖執行dml操作否則會報錯Ad hoc updates to system catalogs are not allowed。了解到這個數據庫實例是從Sqlserver 2000一路升級到Sqlserver 2019,猜測應該是之前有人在Sqlserver 2000的時候有人執行了delete from sys.objects where object_id=1071830442這樣的操作,導致了這樣的問題。了解了原因后,開始嘗試修復操作
1、使用允許數據丟失的修復方式DBCC CHECKDB (‘CacheDBMSIntl’,REPAIR_ALLOW_DATA_LOSS)來修復,發現依舊報和DBCC checkcatalog(‘CacheDBMSIntl’)一樣的錯誤。
2、把這個數據庫備份,再把備份恢復到其他數據庫服務器,在其他數據庫服務器上執行DBCC checkcatalog(‘CacheDBMSIntl’),發現報錯依舊
3、使用安裝軟件的Repair選項發現一樣無法解決。
最后的解決思路是使用copy database的方式重建一個新的CacheDBMSIntl_new,再把CacheDBMSIntl改名為CacheDBMSIntl_old,再把CacheDBMSIntl_new改名為CacheDBMSIntl,至此徹底解決
select * from sys.objects where object_id=1071830442
select * from sys.columns where object_id=1071830442