对数据库CacheDBMSIntl执行DBCC checkcatalog('CacheDBMSIntl')时遇到报错如下
sql
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,至此彻底解决
sql
select * from sys.objects where object_id=1071830442
select * from sys.columns where object_id=1071830442