Tom*_*mas 5 sql-server-2008 sql-server corruption
我有一个包含 15 000 000 条记录的大表,突然 Select Top 停止工作。我使用 MS SQL 管理工作室。
这不起作用,查询返回 0 条记录:
SELECT TOP (10)
[Id]
,[Result]
,[DateStamp]
,[ConversionTime]
,[Converter]
,[SourceFileFormat]
,[DestinationFileFormat]
,[Ip]
,[Source]
,[Error]
,[UserId]
,[TokenId]
,[ConversionCost]
FROM [ca-v2].[dbo].[Log]
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,如果我尝试选择一个 ID 字段,它会正常工作。
工作正常:
SELECT TOP (10)
[Id]
FROM [ca-v2].[dbo].[Log]
Run Code Online (Sandbox Code Playgroud)
此外,如果我在最后添加 order by 查询也开始工作:
SELECT TOP (10)
[Id]
,[Result]
,[DateStamp]
,[ConversionTime]
,[Converter]
,[SourceFileFormat]
,[DestinationFileFormat]
,[Ip]
,[Source]
,[Error]
,[UserId]
,[TokenId]
,[ConversionCost]
FROM [ca-v2].[dbo].[Log]
Order By [DateStamp]
Run Code Online (Sandbox Code Playgroud)
我跑到DBCC CHECKTABLE
桌子上,收到以下错误:
错误:消息 8978,级别 16,状态 1,第 1 行
表错误:对象 ID 1029578706,索引 ID 1,分区 ID 72057594043367424,分配单元 ID 72057594045071360(类型行内数据)。页面 (1:5044) 缺少上一页 (1:5042) 的引用。可能的链条连接问题。
我该怎么办?
在@RDFozz 的帮助下,我能够使用 sql 修复损坏的索引
ALTER DATABASE "db" SET SINGLE_USER WITH ROLLBACK IMMEDIATE
go
DBCC CheckTable ("log", REPAIR_REBUILD)
go
ALTER DATABASE "db" SET MULTI_USER WITH ROLLBACK IMMEDIATE
Run Code Online (Sandbox Code Playgroud)
这里有两件重要的事情:1) 必须将数据库设置为单用户模式。2) 如果数据库在生产中并且有其他连接,则 SET 用户命令必须使用 ROLLBACK IMMEDIATE 来删除当前连接。
RDF*_*ozz 11
当面临数据库损坏时,您需要确定问题的严重程度。你有一个损坏的表/索引,还是很多?您可能希望DBCC CHECKDB
在数据库上运行。
根据您的发现,您有以下选择(按安全降序排列):
从备份恢复
这通常是最简单、最安全的解决方案。但是,如果您不确定损坏是在多久之前出现的,这可能是不切实际的 - 您可能没有最近没有损坏的备份。而且,根据数据库的使用情况,就继续能够运行您的业务而言,丢弃一天的数据来修复损坏可能代价高昂。
但是,如果损坏严重,这可能是您唯一可用的解决方案。即使您尝试了以下某些选项,您也可能需要回到这个选项。
如果您有备份,请将它们放在手边,并且在解决问题之前不要循环使用(如果可能)。
使用DBCC CHECKTABLE
或DBCC CHECKDB
与修复选项一起使用
您的运行DBCC CHECKTABLE
和/或DBCC CHECKDB
可能已经表明您可以使用修复选项来尝试将事情恢复到正常状态。
这些命令具有相同的修复选项:
REPAIR_FAST
- 正如它所说,它尝试了一些简单的事情,并且比其他修复选项花费的时间更少。正如您可能猜到的,这也意味着它最不可能成功。
REPAIR_REBUILD
- 这做了什么REPAIR_FAST
,但也愿意尝试从头开始重建索引 - 问题出在非聚集索引中,这应该可以解决它。
REPAIR_ALLOW_DATA_LOSS
- 正如所指出的,它将尝试将受影响的对象恢复到可用性,但可能必须消除部分行等;您可能会丢失一些数据。这是恢复备份通常是最佳解决方案的原因之一。
Frankensteining 你的坏桌子(可以这么说)
如果只有这张表受到影响,您可以尝试:
DBCC CHECKDB
再次运行确认这没有将您的问题转移到其他地方;和
或者,尝试保留尽可能多的新数据:
REPAIR_ALLOW_DATA_LOSS
在桌子上使用。正如CaM在评论中所指出的,您应该以此为动力,以确保您正在对数据库执行定期维护任务。
首先,如果您不是今天,请开始定期备份它。我管理的大多数数据库都有每周完整备份和每日差异备份,因此我们丢失的数据绝不会超过一天。
此外,您还应该DBCC CHECKDB
定期运行,以便在损坏变得严重而无法修复之前发现损坏。这也是我每周尝试运行的内容。
归档时间: |
|
查看次数: |
4603 次 |
最近记录: |