当SQL SERVER数据库状态为质疑(SUSPECT)状态时,我们可以用以下方法来处理: DBCC报错

1. 修改数据库为紧急模式:ALTER DATABASE DBName SET EMERGENCY .

2. 检查数据库的完整性:DBCC  CHECKDB(‘DBName’)

3. 检查没有错误则恢复数据库为正常模式:ALTER DATABASE  DBName SET ONLINE;

4  如检查数据库有错误则修改数据库为单用户模式,依情况选择以下命令行进行修复数据;

DBCC CHECKDB('DBName',  REPAIR_FAST);

DBCC CHECKDB('DBName',  REPAIR_REBUILD);

DBCC CHECKDB('DBName',  REPAIR_ALLOW_DATA_LOSS);

修复完成后将数据库改为正常模式,重启SQL服务或重启服务器。

   ALTER DATABASE DBName SET EMERGENCY       /* 修改数据库为紧急模式*/
ALTER DATABASE DBName SET SINGLE_USER /* 修改数据库为单用户模式*/
ALTER DATABASE DBName SET MULTI_USER /* 修改数据库为多用户模式*/
ALTER DATABASE DBName SET ONLINE /* 数据库从紧急&单用户&多用户模式恢复为正常模式*/ DBCC CHECKDB('DBName') /* 检查数据库完整性*/
DBCC CHECKDB('DBName', REPAIR_FAST) /* 快速修复数据库*/
DBCC CHECKDB('DBName', REPAIR_REBUILD) /* 重建索引并修复*/
DBCC CHECKDB('DBName', REPAIR_ALLOW_DATA_LOSS) /*如果必要允许丢失数据修复,数据库修复需在单用户模式下进行

数据库质疑修复总结 For SQL Server 2000/2005/2008/2008R2

 转自:https://blogs.msdn.microsoft.com/apgcdsd/2013/06/26/for-sql-server-2000200520082008r2/
 

本文的步骤基于以下条件:

1.     SQL Server可以启动。

2.     数据库没有做有效的备份。

3.     当前用户有Sysadmin权限。

数据库质疑的原因会有多种多样,不同的suspect采用的步骤也会有所不同,以下的步骤不能适用所有的情况,但包括了一些基本的步骤。 数据库suspect是指数据库内部处于不一致的状态,很有可能会有数据丢失。 我们推荐您从“好的数据库备份”恢复。 我们这里所指的“好的数据库备份”是指:

1.  在做数据库备份之前,您检查过DBCC CHECKDB没有错误。

2.  备份之后的数据库没有更改,或者更改可以忽略。

  在做任何修复操作之前,请务必备份.mdf/.ndf以及.ldf文件。

2   SQL Server 2000修复步骤

  如果没有“好的数据库备份”,我们不能保证没有数据丢失。 以下是恢复suspect数据库 (SQL Server 2000)的一般方法,供您参考。 同时在操作下列步骤之前,您可以备份质疑数据库的MDF、NDF、LDF文件,以便以下步骤恢复失败时能够回滚到原来的状态。

1.  在查询分析器中,运行如下命令将数据库置于紧急模式。

  

Sp_configure 'allow update', 1

Go

Reconfigure with override

Go

Begin Tran

Update master..sysdatabases set status = 32768 where name ='<DatabaseName>’

Commit Tran

--此处<DatabaseName>需要替代成您出问题的数据库名字。

--以下同

Go

Select * from sysdatabases

--检查数据库状态是否已经变成 32768

Go

2. 重启SQL Server服务。

3.  如果第二步中重启服务,数据库再次进入suspect模式,请设置数据库紧急模式,使用BCP方式导出数据。

否则在查询分析器中,重新连接到SQL Server,运行如下命令重建日志。

特别注意: dbcc rebuild_log是内部命令,请您阅读附件中的DBCC Rebuild Run Command.doc。 只有当您同意了附件中的内容,才可以运行此命令。

dbcc rebuild_log('<DatabaseName>’,'<The file name and the path of the log file>')

--此处<The file name and the path of the log file>是新的日志文件的物理文件的绝对地址。

go

如果rebuild_log失败,请运行如下命令,

Use <DatabaseName>

Go

如果数据库在emergency 方式能够进入紧急模式,直接使用BCP方式导出数据,没有其他方式来恢复数据库。

如果不能进入,则没有其他方式恢复数据库

如果数据库在Rebuild_log之后恢复正常,进入第四步。

4.  关掉查询分析器,再次打开查询分析器,运行如下语句,查询出问题的数据库的DBID

Select * from master.dbo.sysdatabases

5.  再运行如下命令,检查是否有人在使用当前出问题的数据库,如果有的话,请将他们退出。

  Select * from master.dbo.sysprocesses

6.  然后运行如下命令,将数据库置于单用户使用模式。如果设置不生效,可以尝试使用企业管理器->数据库属性-> 选项来直接设置.

exec sp_dboption N'<DatabaseName>', N'single', N'true'

7.  在查询分析器中,运行如下命令,检查数据库是否有损坏。

  dbcc checkdb(‘<DatabaseName>')

8.  如果您运行上述命令发现数据库有错误。 此时我们需要根据错误来处理。 接下去有两个方向。

方向一:

使用Repair_Allow_Data_Loss选项修复数据库。

优点: 可能可以恢复尽量多的数据

缺点:

a)  不一定能够将全部错误修复,还有可能越修越多。同时,需要大量时间,需要经过多次执行修复命令.十几次,甚至数十次.修复时间不能预估.

b)  就算我们将所有错误修复,我们也不能保证数据在应用程序逻辑这一层次上的数据正确性,您需要找您的应用程序提供商来检查数据在程序逻辑层次是否正确。

dbcc checkdb ('<DB_name>', REPAIR_ALLOW_DATA_LOSS) go

--此命令可能需要运行多次,才能完全修复。

方向二:

通过BCP,DTS,select into等方式将好的表,或者表中好的数据导出来。建议使用BCP的方法,这样可以最大限度的回复数据.BCP会停在出错的纪录上,但是前面的数据就能成功导出.使用DTS或Select into的话, 我们很难判断最大限度能导出的记录数.

优点:导出来的数据保证在应用程序逻辑这一层次的正确性

缺点:不会修复数据库中存在的错误,丢失的数据量会比较大,取决于第7步的运行结果。

9.  数据库完全恢复正常之后,将数据库置于正常状态,并将单用户模式改成多用户模式。(16或者0)

begin tran

  update sysdatabases set status = 8 where name = 'db_name'

commit tran

sp_configure 'allow', 0

reconfigure with override

exec sp_dboption N'<DatabaseName>', N'single', N'false'

另外,在上述步骤之前或者之中,可能会有数据库在企业管理器中看不到,并且无法attach的状况。 通常可以建同名数据库(注意:物理文件名也要一致),停止SQL Server,覆盖文件,重启SQLServer的方式来解决。

3   SQL Server 2005/2008/2008R2修复步骤

方法一

  


use master
alter database <DatabaseName>set emergency  --设置为紧急模式

alter database <DatabaseName>set single_user with rollback immediate  --设置为单用户模式

use <DatabaseName>  --切换到故障数据库

dbcc checkdb  --检查故障数据库

use master  --切换到master

alter database <DatabaseName>Rebuild Log on  --重建日志文件

(name=<DatabaseName>_log,filename='c:\sql\logs\<DatabaseName>_log.LDF')

select * from sys.databases  --验证是否重建成功

dbcc checkdb('<DatabaseName>', repair_allow_data_loss)  --允许丢失数据修复

sp_dboption '<DatabaseName>','single user','false'

方法二

alter database <DatabaseName> set emergency

go

alter database <DatabaseName> set single_user with rollback immediate

go

use master

go

alter database <DatabaseName> Rebuild Log on

(name=<DatabaseName>_log,filename='c:\sql\logs\<DatabaseName>_log.LDF')

go

use <DatabaseName>

go

dbcc checkdb

go

--此时checkdb有错误才需要做步骤d)

d) 此时数据库应处于emergency状态,创建一个新数据库,通过bcp/bulk insert/DTS/SSIS方式将数据导出到新的数据库.

请注意,这种情况下索引,存储过程,视图等,都需要手工导出来。

4             导数据总结

1. 创建一个空的数据库。

2. 使用脚本禁用所有外键约束。

Use <NewDatabase>

GO

DECLARE @disable BIT

set @disable= 1

DECLARE

    @sql VARCHAR(500),

    @tableName VARCHAR(128),

    @foreignKeyName VARCHAR(128)

-- A list of all of the Foreign Keys and the table names

DECLARE foreignKeyCursor CURSOR

    FOR

SELECT

        ref.constraint_name AS FK_Name,

        fk.table_name AS FK_Table

      FROM

        INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS ref

        INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS fk ON ref.constraint_name =fk.constraint_name

      ORDER BY

        fk.table_name,

        ref.constraint_name

OPEN foreignKeyCursor

FETCH NEXT FROM foreignKeyCursor INTO @foreignKeyName, @tableName

WHILE ( @@FETCH_STATUS = 0 )

    BEGIN

     IF @disable = 1

        SET @sql = 'ALTER TABLE [' + @tableName + '] NOCHECK CONSTRAINT [' + @foreignKeyName +']'

     ELSE

        SET @sql = 'ALTER TABLE [' + @tableName + '] CHECK CONSTRAINT [' + @foreignKeyName + ']'

        PRINT 'Executing Statement - ' + @sql

     EXECUTE(@sql)

        FETCH NEXT FROM foreignKeyCursor INTO @foreignKeyName, @tableName

    END

CLOSE foreignKeyCursor

DEALLOCATE foreignKeyCursor

    Go

3. 使用脚本禁用所有触发器。

DECLARE    @disable BIT

set @disable= 1

 DECLARE

        @sql VARCHAR(500),

        @tableName VARCHAR(128),

        @tableSchema VARCHAR(128)

-- List of all tables

    DECLARE triggerCursor CURSOR

        FOR

SELECT

        t.TABLE_NAME AS TableName,

        t.TABLE_SCHEMA AS TableSchema

      FROM

        INFORMATION_SCHEMA.TABLES t

      ORDER BY

        t.TABLE_NAME,

        t.TABLE_SCHEMA

    OPEN triggerCursor

    FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema

    WHILE ( @@FETCH_STATUS = 0 )

        BEGIN

            IF @disable = 1

                SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] DISABLE TRIGGER ALL'

            ELSE

                SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] ENABLE TRIGGER ALL'

            PRINT 'Executing Statement - ' + @sql

            EXECUTE ( @sql )

            FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema

        END

    CLOSE triggerCursor

    DEALLOCATE triggerCursor

4.     生成脚本并执行启用Identity_Insert。

select 'SET IDENTITY_INSERT dbo.['+ name +'] on 

go'

from dbo.sysobjects

where type='U'

5.     自动生成脚本导入数据到新的数据库中。(对于存在计算列或者Identity字段的表需要手动修改语句)

select 'insert into NewDB.dbo.'+ name +' select * from '+ name

from dbo.sysobjects

where type='U'

6.     使用脚本启用所有外键约束,触发器,禁用Identity_Insert。

启用外键:

DECLARE  @disable BIT

set @disable= 0

DECLARE

    @sql VARCHAR(500),

    @tableName VARCHAR(128),

    @foreignKeyName VARCHAR(128)

-- A list of all of the Foreign Keys and the table names

DECLARE foreignKeyCursor CURSOR

    FOR

  SELECT

        ref.constraint_name AS FK_Name,

        fk.table_name AS FK_Table

      FROM

        INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS ref

        INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS fk ON ref.constraint_name =fk.constraint_name

      ORDER BY

        fk.table_name,

        ref.constraint_name

OPEN foreignKeyCursor

FETCH NEXT FROM foreignKeyCursor INTO @foreignKeyName, @tableName

WHILE ( @@FETCH_STATUS = 0 )

    BEGIN

      IF @disable = 1

         SET @sql = 'ALTER TABLE [' + @tableName + '] NOCHECK CONSTRAINT [' + @foreignKeyName +']'

      ELSE

         SET @sql = 'ALTER TABLE [' + @tableName + '] CHECK CONSTRAINT [' + @foreignKeyName + ']'

        PRINT 'Executing Statement - ' + @sql

      EXECUTE(@sql)

        FETCH NEXT FROM foreignKeyCursor INTO @foreignKeyName, @tableName

    END

CLOSE foreignKeyCursor

DEALLOCATE foreignKeyCursor

     Go

启用触发器:

DECLARE  @disable BIT

set @disable= 0

 DECLARE

        @sql VARCHAR(500),

        @tableName VARCHAR(128),

        @tableSchema VARCHAR(128)

    -- List of all tables

    DECLARE triggerCursor CURSOR

        FOR

    SELECT

        t.TABLE_NAME AS TableName,

        t.TABLE_SCHEMA AS TableSchema

      FROM

        INFORMATION_SCHEMA.TABLES t

      ORDER BY

        t.TABLE_NAME,

        t.TABLE_SCHEMA

    OPEN triggerCursor

    FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema

    WHILE ( @@FETCH_STATUS = 0 )

        BEGIN

            IF @disable = 1

                SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] DISABLE TRIGGER ALL'

            ELSE

                SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] ENABLE TRIGGER ALL'

            PRINT 'Executing Statement - ' + @sql

            EXECUTE ( @sql )

            FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema

        END

    CLOSE triggerCursor

DEALLOCATE triggerCursor

禁用Identity_Insert:

select 'SET IDENTITY_INSERT dbo.['+ name +'] off 

go'

from dbo.sysobjects

where type='U'

5       附录

我们可以看到,数据库恢复是一个非常复杂也是非常不可靠的方式,这就要求我们事先做好数据库的备份。以下是我们对数据库备份的一些基本策略,供您参考。

1.对所有的数据库来说,备份策略取决于数据库被修改的频繁程度,以及数据库的重要程度。一般来说,系统数据库不像用户数据库那样会经常的修改。重要的系统数据库有:

  Master

  Master 数据库存储了SQL Server 系统一级的信息,是最重要的数据库。它还包括所有的登陆帐号和所有的系统配置信息。同时它还存储了SQL Server还包含哪些数据库(包括用户数据库),这些数据库存在哪个地方等等信息。

  MSDB

  MSDB 数据库包含了所有作业的的内容和调度信息等等。

  我们建议您每一个星期备份一次系统数据库。同时当您手动更改过系统数据库时,应该立即手动备份一次。比如添加了一个用户,新建了一个数据库,更改了一个作业等等。

2.对所有的用户数据库,如果它是一个重要的数据库,除了用完全的恢复模式外,还需要调度备份您的数据库:

  A)完全备份每周一次

  B)差异备份每天或者每半天一次

  C)日志备份每小时或者半小时一次

注意:

  A)所有的这些都可以用数据库维护计划来完成(Maintenance Plan),同时它也可以自动删除旧的文件,比如说4周之前的,以避免磁盘空间不够的问题。

  B)我们不建议备份到网络磁盘上。以我们的经验,直接备份到网络磁盘会有些问题。

  C)上述备份时间周期仅供参考,您需要根据实际情况制定计划。

数据库被置疑主要是因为数据库data文件或者日志文件损坏. Data文件就是MDF、NDF文件,日志就是事务日志, 通常是LDF文件.

文件损坏的原因有:

(1) 一个最常见的原因是磁盘问题. 如果数据库文件因为磁盘原因而binary受到损坏,那么SQL Server 往往不能从文件正常读取数据,这个时候很容易导致数据库置疑. 对于这种情况, 你往往可以从机器的系统日志中发现磁盘相关的错误. 在SQL Server 的错误日志中也常常可以看到823错误:

错误 823 严重级别 24 消息正文

在文件 ''%4!'' 的偏移量 %3! 处的 %2! 过程中,检测到 I/O 错误 %1!。

注意损坏可以是静态的损坏, 比如磁盘某磁道的问题而导致文件的某部分不能被正常读取等. 也可以是动态的.比方说由于硬件问题,文件在SQL Server 的读写过程中损坏.

(2) 如果SQL Server还在运行而机器突然断电或热启动,那么数据库文件就有损坏的可能.

(3) 一些病毒也可以导致文件损坏

(4) 人为的因素. 比方说日志文件被误删等.

6             引用

Disabling Constraints and Triggers (Quite useful)

http://msdn.microsoft.com/en-us/magazine/cc163442.aspx

联机丛书的管理SQL Server -> 备份和还原数据库这一章节

关于SQL Server 备份和恢复的文章

http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/sqlbackuprest.mspx

SQL Server 的高可用性

http://support.microsoft.com/?id=822400

How to move SQL Server databases to a new location by using Detach and Attach functions in SQL Server

http://support.microsoft.com/kb/224071

数据库质疑修复(SUSPECT)总结,DBCC报错的更多相关文章

  1. 连接远程MySQL数据库项目启动时,不报错但是卡住不继续启动的,

    连接远程MySQL数据库项目启动时,不报错但是卡住不继续启动的, 2018-03-12 17:08:52.532DEBUG[localhost-startStop-1]o.s.beans.factor ...

  2. dotnetcore ef 调用多个数据库时用户命令执行操作报错

    dotnetcore ef 调用多个数据库时用户命令执行操作报错 1.多个DbContext 时报错: 报错: More than one DbContext was found. Specify w ...

  3. Oracle数据库误删文件导致rman备份报错RMAN-06169解决办法

    Oracle数据库误删文件导致rman备份报错RMAN-06169解决办法 可能是误删文件导致在使用rman备份时候出现以下提示 RMAN-06169: could not read file hea ...

  4. vue-electron 使用sqlite3数据库,执行npm run build 报错 .NET Framework 2.0 SDK,Microsoft Visual Studio 2005[C:\temp\wechat\node_modules\sqlite3\build\binding.sln]

    问题描述 vue-electron 使用sqlite3数据库,执行npm run build 报错如下: .NET Framework 2.0 SDK,Microsoft Visual Studio ...

  5. ORACLE数据导入导出后新数据库中某些表添加操作报错[ORA-12899]

    由于项目需要,我在搭建了新的开发环境后,需要将之前环境中的ORACLE数据库导出,再导入到新的开发环境下.当导出导入完成后,使用数据库进行添加操作时 发现针对很多表的添加操作报错,具体报错原因描述为: ...

  6. MySQL数据库储存bit类型的值报错

    当我们储存bit类型的值时,不能直接写入数字 上图中的画圈部分就是bit类型,若是直接填入"1"或"0"等等就会报错,如下: 这时候,我们要看bit(M)的M值 ...

  7. Mycat分布式数据库架构解决方案--配置defaultAccount属性报错解决方案

    echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! 该文章 ...

  8. flask从数据库反向导入Model以及出现报错No module named sqlacodegen.main

    使用flask的朋友肯定了解了flask_sqlalchemy,不了解的小伙伴也可以查看博文:Flask 操作Mysql数据库 - flask-sqlalchemy扩展 上面博文中讲解了如何将flas ...

  9. IDEA(2018)连接MySQL数据库失败的解决方法(报错08001)

     解决方法: 将url改成: jdbc:mysql://localhost:3306/studentmanage?useSSL=true&serverTimezone=Hongkong& ...

随机推荐

  1. MTU的概念,什么是路径MTU? MTU发现机制,TraceRoute(了解)

    1.MTU的概念      MTU即Maximum Transmission Unit 最大传输单元.它是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位). 2.路径MTU     ...

  2. CSS 温故而知新 background常用属性

    1.background-repeat 不用说,常用直接no-repeat 2.background-size 常用的分为两个,一个是铺满:cover, 另一个是使图像适应宽高:contain 3.b ...

  3. atitit.atiLinq v2新特性attilax大总结 q326

    atitit.atiLinq v2新特性attilax大总结 q326 1. V3规划 (分开sql2obj sql2sql sql2xml)1 2. V2新特性 Url linq的定义1 3. V1 ...

  4. Xilinx DDR3 IP核使用问题汇总(持续更新)和感悟

    一度因为DDR3的IP核使用而发狂. 后来因为解决问题,得一感悟.后面此贴会完整讲述ddr3 ip的使用.(XILINX K7) 感悟:对于有供应商支持的产品,遇到问题找官方的流程.按照官方的指导进行 ...

  5. 使用pycharm手动搭建python语言django开发环境(三) 使用django的apps应用 添加应用静态文件

    1)在django 工程目录中使用cmd命令行 敲入"python manage.py startapp app名称(例子为blog)" 2)在django工程目录中应该生成了bl ...

  6. LeetCode406. Queue Reconstruction by Height Add to List

    Description Suppose you have a random list of people standing in a queue. Each person is described b ...

  7. Spring MVC生成XML

    以下示例演示如何使用Spring Web MVC框架生成XML.首先使用Eclipse IDE,并按照以下步骤使用Spring Web Framework开发基于动态表单的Web应用程序: 创建一个名 ...

  8. KMP hihoCoder1015 KMP算法

    人太蠢,,看了一天的KMP.. 刚開始看训练指南的,,后来才惊奇的发现原来刘汝佳写的f数组并非Next数组! 总认为和之前看过的全然不一样.. . 后来又百度了一下KMP,研究了非常久,然后用自己的逻 ...

  9. iOS --转载2018苹果$299美元企业级开发者账号申请攻略

    前言篇 现在苹果企业级开发者账号申请十分严格,大部分企业都无法申请下来,本人尝试过多次申请,现将一些审核技巧分享出来,希望能帮到你们通过申请,需要帮助请看本文最后 2018年6月7号申请成功案例   ...

  10. ios 2017启动页(Launch Screen Images)、图标(App Icon)尺寸大小

    ios 2017启动页(Launch Screen Images).图标(App Icon)尺寸大小   iPhone Portrait iOS 8,9-Retina HD 5.5 (1242×220 ...