由于数据库的机器是一个比较老的机器了,而且每天会存在大批量的读写。有得时候机器会被意外的关闭。在这个意外的关闭过程中,正好在进行数据的写入。结果是数据库被置疑了。很郁闷的一件事情。这里分享下我的解决方法。
一、将数据库从质疑状态恢复。
1、首先置疑的数据库不能备份。试着备份下,如果可以的话可以先备份下。
2.把数据库设成紧急状态:
然后在SQL查询分析器中,选到master数据库,输入以下语句执行(一条一条执行)
sp_configure 'allow',1
reconfigure with override
update sysdatabases set status=32768 where name='数据库名字'
2.重建日志文件:
[DATABASE NAME:数据库名称] _log3.ldf为一个新的不存在的文件,在执行以下语句时将自动建立
dbcc rebuild_log('dbname','E:\KLSMSDB\dbname_log3.ldf')
3.取消紧急模式(一条一条执行)
update sysdatabases set status=0 where name='KLSMS'
restore database [KLSMS] with recovery
sp_configure 'allow',0
reconfigure with override
4.重起sql server,看OK不。
如果上面的步骤不能完成,一般会提示有多个用户操作,处理失败。可以在做上边4个步骤前将数据库设为单人独占模式。流程如下:
在电脑---管理---服务里面重启MSSQLSERVER服务,在启动的瞬间执行如下代码:
use master
declare @databasename varchar(255)
set @databasename='数据库名称'
exec sp_dboption @databasename, N'single', N'true'-- –将目标数据库置为单用户状态,多尝试几次。
二、经过以上步骤的操作,现在数据库已经不是质疑状态了。
1、 重启服务器后,在没有进行任何操作的情况下,在SQL查询分析器中执行以下SQL进行数据库的修复,修复数据库存在的一致性错误与分配错误。
use master
declare @databasename varchar(255)
set @databasename='需要修复的数据库实体的名称'
exec sp_dboption @databasename, N'single', N'true' --将目标数据库置为单用户状态
dbcc checkdb(@databasename,REPAIR_ALLOW_DATA_LOSS)
dbcc checkdb(@databasename,REPAIR_REBUILD)
exec sp_dboption @databasename, N'single', N'false'--将目标数据库置为多用户状态
然后执行 DBCC CHECKDB('需要修复的数据库实体的名称') 检查数据库是否仍旧存在错误。注意:修复后可能会造成部分数据的丢失。
2、这个时候就要一个一个的检查是否有表受损。我的检查方法有点笨拙,就是做一个全表查询。如果查询报错,会提示:
"消息 605,级别 21,状态 1,第 2 行
Attempt to fetch logical page (1:8248544) in database 'DBNAME' belongs to object '表名2', not to object '表名'.
消息 605,级别 21,状态 1,第 2 行
试图从数据库 'dbname' 中提取的逻辑页 (1:8248544) 属于对象 '表名2',而非对象 '表名'。"说明这个表受损了。我的理解是正好这个表在读取另外一个表要写入的过程中机器运行故障了。
3、然后就是修复表。修复表一定要独占单用户模式才可以。代码如下:
use dbname
declare @dbname varchar(255)
set @dbname='dbname'
exec sp_dboption @dbname,'single user','true' ---设为单用户用户
dbcc checktable('表名1',REPAIR_ALLOW_DATA_LOSS)
dbcc checktable('表名1',REPAIR_REBUILD) ---修复表1
dbcc checktable('表名2',REPAIR_ALLOW_DATA_LOSS)
dbcc checktable('表名2',REPAIR_REBUILD) ---修复表2
exec sp_dboption 'dbname','single user','false' ---设为多用户
4、对修复的表重建索引。
use DBNAME
DBCC DBREINDEX ('表名1','')
DBCC DBREINDEX ('表名2','')
经过以上操作数据库就恢复过来了。