求助:我的sqlserver突然之间数据库msdb无法打开,企业管理器里面在msdb旁边显示“置疑”,导致数据库的作业调度用不了了,不知是设那么


楼主jsys(雪狼) 2004-05-08 14:10:40 在 MS-SQL Server / 应用实例 提问


求助:我的sqlserver突然之间数据库msdb无法打开,企业管理器里面在msdb旁边显示“置疑”,导致数据库的作业调度用不了了,不知是设那么原因?如何解决? 问题点数:100、回复次数:4Top

1 楼zjcxc(邹建)回复于 2004-05-08 14:14:56 得分 50

重置置疑状态  
  如果   SQL   Server   因为磁盘驱动器不再有可用空间,而不能完成数据库的恢复,那么   Microsoft®   SQL   Server™   2000   会返回错误   1105   并且将   sysdatabases   中的   status   列设为置疑。按下面的步骤解决这个问题:    
   
  执行   sp_resetstatus。  
   
   
  用   ALTER   DATABASE   向数据库添加一个数据文件或日志文件。  
   
   
  停止并重新启动   SQL   Server。    
  用新的数据文件或日志文件所提供的额外空间,SQL   Server   应该能完成数据库的恢复。  
   
  释放磁盘空间并且重新运行恢复操作。    
  sp_resetstatus   关闭数据库的置疑标志,但是原封不动地保持数据库的其它选项。  
   
   
   
  注意     只有在您的主要支持提供者指导下或有疑难解答建议的做法时,才可以使用   sp_resetstatus。否则,可能会损坏数据库。  
   
   
  由于该过程修改了系统表,系统管理员必须在创建这个过程前,启用系统表更新。要启用更新,使用下面的过程:  

USE   master   
  GO   
  sp_configure   'allow   updates',   1   
  GO   
  RECONFIGURE   WITH   OVERRIDE   
  GO   
    
  过程创建后,立即禁用系统表更新:   
    
  sp_configure   'allow   updates',   0   
  GO   
  RECONFIGURE   WITH   OVERRIDE   
  GO   
    
  只有系统管理员才能执行   sp_resetstatus。执行该过程后,立即关闭   SQL   Server。   
    
  语法为:   
    
  sp_resetstatus   database_name   
    
  下面的例子将关闭   PRODUCTION   数据库的置疑标志。   
    
  sp_resetstatus   PRODUCTION   
    
  下面是结果集:   
    
  Database   'PRODUCTION'   status   reset!   
  WARNING:   You   must   reboot   SQL   Server   prior   to   accessing   this   database!   
    
  sp_resetstatus   存储过程代码   
  下面是   sp_resetstatus   存储过程的代码:   
    
  IF   EXISTS   (   SELECT   *   from   sysobjects   where   name   =   'sp_resetstatus'   )   
        DROP   PROCEDURE   sp_resetstatus   
  GO   
    
  CREATE   PROC   sp_resetstatus   @dbname   varchar(30)   AS   
  DECLARE   @msg   varchar(80)   
  IF   @@trancount   >   0   
              BEGIN   
                    PRINT   'Can''t   run   sp_resetstatus   from   within   a   transaction.'   
                    RETURN   (1)   
              END   
  IF   suser_id()   !=   1   
              BEGIN   
                    SELECT   @msg   =     'You   must   be   the   System   Administrator   (SA)'   
                    SELECT   @msg   =   @msg   +   '   to   execute   this   procedure.'   
                    RETURN   (1)   
              END   
  IF   (SELECT   COUNT(*)   FROM   master..sysdatabases   
                    WHERE   name   =   @dbname)   !=   1   
              BEGIN   
                    SELECT   @msg   =   'Database   '   +   @dbname   +   '   does   not   exist!'   
                    PRINT   @msg   
                    RETURN   (1)   
              END   
  IF   (SELECT   COUNT(*)   FROM   master..sysdatabases   
                    WHERE   name   =   @dbname   AND   status   &   256   =   256)   !=   1   
              BEGIN   
                    PRINT   'sp_resetstatus   can   only   be   run   on   suspect   databases.'   
                    RETURN   (1)   
              END   
  BEGIN   TRAN   
              UPDATE   master..sysdatabases   SET   status   =   status   ^   256   
                    WHERE   name   =   @dbname   
              IF   @@error   !=   0   OR   @@rowcount   !=   1   
                    ROLLBACK   TRAN   
              ELSE     
                    BEGIN   
                          COMMIT   TRAN   
                          SELECT   @msg   =   'Database   '   +   @dbname   +   '   status   reset!'   
                          PRINT   @msg   
                          PRINT   ''   
                          PRINT   'WARNING:   You   must   reboot   SQL   Server   prior   to     '   
                          PRINT   '                   accessing   this   database!'   
                          PRINT   ''   
                    END   
  GO


   
  Top

2 楼progress99(如履薄冰)回复于 2004-05-08 14:15:39 得分 50

看看大大版主leimin的:  
   
  在MS   SQLSERVER中一直有这样的问题,SQLSERVER的状态"置疑",我们先来分析一下SQLSERVER数据库"置疑"的原因:  
        1.错误的删除日志;  
        2.硬件(HD)损坏,造成日志和数据文件写错误;  
        3.硬盘的空间不够,比如日志文件过大;  
   
   
  解决办法:  
   
  这是最简单的办法是有数据库的全备份,然后恢复即可.  
  步骤:  
   
  1.   删除原始的数据库:  
         

USE   MASTER   
            GO     
            DROP   DATABASE   DB_SUEPECT   
            
    
  2.建立同名的数据库:   
                  USE   master   
                GO   
                CREATE   DATABASE   DB_SUSPECT   
                  ON   
                    (   NAME   =   DBNAME_DAT,   
                        FILENAME   =   'C:',   
                        SIZE   =   10,   
                          FILEGROWTH   =   5   )   
                        LOG   ON   
                      (   NAME   =   'DBNAME_LOG',   
                        FILENAME   =   'g:',   
                        SIZE   =   5MB,   
                        FILEGROWTH   =   5MB   )   
                        GO   
            
    
  3.恢复数据库:   
              RESTORE   DATABASE   DB_SUSPECT   
            FROM   DBNAME_BACKUP.DAT


  4.数据库完整性检测:  
                DBCC   CHECKDB('DB_SUSPECT')  
   
  5.重新启动MSSQLSERVER服务.  
   
  如果没有全备份,那就要用一些特殊的方法:  
   
  1.设置数据库为紧急模式  
                Use   Master  
                GO  
                sp_configure   'allow   updates',   1  
                reconfigure   with   override  
              GO  
              UPDATE   sysdatabases   SET   status   =   32768   where   name   =   'DB_SUSPECT'  
              GO  
   
  2.停掉SQL   Server服务:  
            NET   STOP   MSSQLSERVER  
   
  3.把原始数据库的数据文件DBNAME_DAT.MDF,DBNAME_LOG.LDF移走:  
   
  4.启动SQL   Server服务:  
              NET   START   MSSQLSERVER  
   
  5.重新建立一个同名的数据库DB_SUSPECT;  
   
                USE   master  
                GO  
                CREATE   DATABASE   DB_SUSPECT  
                  ON  
                    (   NAME   =   DBNAME_DAT,  
                        FILENAME   =   'C:',  
                        SIZE   =   10,  
                          FILEGROWTH   =   5   )  
                        LOG   ON  
                      (   NAME   =   'DBNAME_LOG',  
                        FILENAME   =   'g:',  
                        SIZE   =   5MB,  
                        FILEGROWTH   =   5MB   )  
                        GO  
   
   
  6.设置数据库运行在单用户的模式:  
                    USE   MASTER  
                  GO  
                  ALTER   DATABASE   DB_SUSPECT   SET   SINGLE_USER  
                  GO  
   
  7.停掉SQL服务:  
            NET   STOP   MSSQLSERVER  
   
  8.把原来的数据文件再覆盖回来:  
   
   
  9.启动SQL   Server服务:  
              NET   START   MSSQLSERVER  
   
  10.重新设置SQLSERVER的状态:  
                    USE   MASTER  
                  GO  
                  EXEC   sp_resetstatus   "DB_SUSPECT"  
   
  11.数据库完整性检测:  
                  DBCC   CHECKDB('DB_SUSPECT')  
   
  12.恢复数据库为多用户模式:  
                  USE   MASTER  
                  GO  
                  ALTER   DATABASE   DB_SUSPECT   SET   MULTI_USER  
                GO  
   
  13.恢复SQLSERVER原始的配置:  
              USE   MATER  
   
          GO            
   
          UPDATE   sysdatabases   SET   status   =   4194320   where   name   =   'DB_SUSPECT'  
          GO  
   
  14.配置SQLSERVER不允许更新系统表:  
              USE   MASTER  
            GO  
              sp_configure   'allow   updates',   0  
              reconfigure   with   override  
            GO  
   
  15.重新启动MSSQLSERVER服务:  
   
            最好重新启动操作系统  
   
  16.备份数据库:  
   
        可以通过SQLSERVER企业管理器或T-SQL.需要备份MASTER和DB_SUSPECT  
   
     
   
     
   
  对该贴的补充:  
  1.如果不需要恢复到指定的时间点,你可以将数据库的恢复模式配置为简单,这样  
  UPDATE,DELETE,SELECT就不会记录日志,日志就不会增加的很大:  
      ALTER   DATABASE   DB_NAME   SET   RECOVERY   SIMPLE  
  2.如果你的恢复模式是全部,你一定要配置日志字段收缩:  
          sp_dboption   'databasename','trunc.   log   on   chkpt.',true  
          sp_dboption   'databasename','autoshrink',true  
  3.通过每日备份将日志收缩:  
      BACKUP   DATABASE   DATABASE_NAME   TO   BACKUP_DEVICES  
      BACKUP   LOG   DATABASE_NAME   TO   LOG_DEVICES  
      OR  
      BACKUP   LOG   DATABASE_NAME   with   truncate_only  
   
      **检查日志的容量:DBCC   SQLPERF   (LOGSPACE)   这时日志并没有收缩!  
   
  4.每天在备份数据库完成之后,重新启动MS   SQLSERVER   SERVICE.  
                  USE   DATABASE_NAME  
                  go  
                  DBCC     SHRINKFILE(2,truncateonly)  
   
      **检查日志的容量:DBCC   SQLPERF   (LOGSPACE)   这时日志已经收缩!  
   
  5.手动快速收缩日志:  
      /   *run     below     script,you     will     shrink     you     database     log     files  
  immediately,     in     my     experience,you     need     to     run     the     script     for     3     or  
  4     minutes     before   stopping     it     manually     */  
  use     databasename  
  dbcc     shrinkfile(2,notruncate)  
  dbcc     shrinkfile(2,truncateonly)  
  create     table     t1(char1     char(4000))  
  go  
  declare     @i     int  
  select     @i=0  
  while(1=1)  
  begin  
          while(@i<100)  
                          begin  
                      INSERT     INTO     T1     VALUES     ('A')  
                      SELECT     @I=@I+1  
                      END  
  TRUNCATE     table     T1  
  BACKUP     LOG     youdatabasename     with     truncate_only  
  end  
  go