错误提示:
消息 829,级别 21,状态 1,第 1 行 数据库 ID 15,页 (1:21826) 已标记为 RestorePending,可能表明磁盘已损坏。要从此状态恢复,请执行还原操作。
引起原因:
RestorePending一般是在进行页恢复的过程中出现的,就是在进行了restore操作之后但还没有进行recovery操作之前页的状态。
出现这样的问题可以肯定这个表是损坏了,但是在查询数据的时候如果不会查询到损坏页面的数据话是不会报错的,也就是说可以有条件的使用这个表。
如果损坏的页只有一个的话,那删除掉这个坏表故障肯定就没有了,因为一个页里面只会放一个表的数据。
损坏的直接原因就是放在磁盘上面的数据被意外的修改了或者写入的时候出错这些,可能是磁盘问题,但是IO系统可能性更大。
可以好好的检查系统日志和SQLServer的LOG,看看里面有没有关于磁盘或者IO之类的警告、报错信息,以进一步确定原因。
至于处理方法,如果表重要那就利用备份做页面还原恢复数据,不重要的话就删掉重建,
或者使用以下方式进行修复,在处理完坏页之后再对整个数据库做一次DBCC CHECKDB操作,确保没有其他的坏页。
解决办法:
快速修复 DBCC CHECKDB ('数据库名', REPAIR_FAST)
重建索引并修复 DBCC CHECKDB ('数据库名', REPAIR_REBUILD)
如果必要允许丢失数据修复 DBCC CHECKDB ('数据库名'', REPAIR_ALLOW_DATA_LOSS)
错误提示:
执行修复命令时,可能会出现以下错误:
未处理修复语句。数据库需处于单用户模式下解决
解决办法:
此时我们需要将数据库设置成单用户模式:
右键点击数据库 -> 属性 -> 选项 -> 状态 -> 限制访问 -> 选择Single-> 确定。
错误提示:
当我们修复完数据库后,需要将其恢复为多用户模式,此时可能出现
数据库 'xxx' 已打开,并且一次只能有一个用户访问
解决办法:
在设置多用户模式的时候可能会因为还有其它进程的连接导致设置无法进行,所以需要杀掉所有连接的进程。
方式一
USE master; GO DECLARE @SQL VARCHAR(3000); SET @SQL = ''; SELECT @SQL = @SQL+'; KILL ' + RTRIM(SPID) FROM [sys].[sysprocesses] AS sps WHERE [sps].[dbid] = DB_ID('test'); SET @SQL = SUBSTRING(@SQL, 2, LEN(@SQL)); EXEC(@SQL); GO
方式二
DECLARE @DBName SYSNAME; SET @DBName = 'BI_Monitor'; --这个是要删除的数据库库名 DECLARE @KSQL NVARCHAR(1000) DECLARE tb CURSOR LOCAL FOR SELECT KSQL = 'KILL ' + CAST([sps].[spid] AS NVARCHAR(10)) FROM [sys].[sysprocesses] AS sps WHERE dbid = DB_ID(@DBName)--查询@DBName相关的线程 --循环杀掉要删除数据的相关线程 OPEN tb FETCH NEXT FROM tb INTO @KSQL WHILE @@FETCH_STATUS = 0 BEGIN EXECUTE(@KSQL); FETCH NEXT FROM tb INTO @KSQL END CLOSE tb DEALLOCATE tb
最后再将相应数据库设置为多用户模式即可。
ALTER DATABASE [test] SET MULTI_USER;--设置为多用户模式