zoukankan      html  css  js  c++  java
  • 记录SQL Server2008日志文件损坏的恢复过程

    记录SQL Server2008日志文件损坏的恢复过程:

    环境:

     系   统:Windows Server2003
    
     数据库:SQL Server2008

    故障原因:

    通过mstsc链接同一服务器时,用户界面不一致。决定重启服务器,未正确关闭应用程序的情况下(程序在访问数据库),导致数据库日志文件损坏,自然也就无法访问mdf文件!(都是微软自家的产品,重启服务器为什么不能检查数据库的状态,将数据库设置在安全状态后在重启呢??(有一种解释是:SQL Server为了加快关机的速度,允许使用NOWAIT选项。此选项将跳过检查点操作,导致部分数据未回写到MDF文件(仅记录在LDF中)。在这种情况下,如果丢失了LDF文件,尽管可以修复数据库,却会有数据丢失)所以,要养成良好的习惯。关闭现有数据库链接,再重启服务器)
    
    故障表现:无法访问数据文件,就像下面JD_2数据库一样。

                                                          

    解决方案:

    1:将数据库JD_2删除、或者分离(这里可能会提示无法删除或分离数据库,可以重启对应的数据库实例后再次尝试)
    
    2:新建数据库,日志文件和数据文件名称和要恢复对应文件一样命名。
    
    3:将新建的数据库设置为脱机模式,找到新建数据库的物理路径,将要恢复的mdf文件拷贝覆盖现有的mdf文件。
    
    4:设置数据库为联机模式,刷新数据库,可以看到并没有什么卵用。
    
    5:执行alter database JD_2 set emergency  将数据库设置为紧急模式。
    
    执行:
     1 use master 
     2 
     3 declare @databasename varchar(255) 
     4 
     5 set @databasename='JD_2' 
     6                                                                  
     7 ALTER DATABASE JD_2 SET SINGLE_USER   //将目标数据库置为单用户状态 
     8 
     9 dbcc checkdb(@databasename,REPAIR_ALLOW_DATA_LOSS) 
    10 
    11 dbcc checkdb(@databasename,REPAIR_REBUILD) 
    12 
    13 ALTER DATABASE JD_2 SET MULTI_USER //将目标数据库置为多用户状态 
    6:刷新后数据库处于紧急模式,数据基本恢复。当前数据局处于紧急模式,无法对数据库备份,无法增删改查,只能读取。所以我们要恢复紧急模式为正常模式

                                                                   

    7:执行 select * from sys.master_files 查看数据库基本信息和状态信息
    
    8:执行 select * from sysdatabases 查看所有数据库的信息如下:
    
       Status状态码含义:http://blog.csdn.net/nemo2011/article/details/9233777

                                            

    执行:
    
    方案1:
    1 sp_configure 'allow updates',1
    2 reconfigure with override
    3 update sysdatabases set status=0 where name='JD_New'
    更改数据库状态码,提示不允许更改=>sql server2008不支持对系统表的修改
    
    方案2:
    
    对于正常未损坏的数据库可以使用
    1 ALTER DATABASE dbname SET EMERGENCY 
    2 
    3 ALTER DATABASE dbname SET ONLINE
    在紧急模式和普通模式间切换。但是对于损坏过的数据,经验证此方法行不通。
    
    参考了一些网上的办法,都没能解决问题!请朋友不吝赐教~~
    
    如果只是关心数据库表中的基础数据,可以新建数据库,将待恢复的数据批量导入到新的数据库中执行以下语句(修改DatabaseFrom为损坏数据库名称、DatabaseTo为新数据库名称即可;210、11行)=>
     1 USE [DatabaseFrom]
     2 
     3 DECLARE @fromdb VARCHAR(100)
     4 DECLARE @todb VARCHAR(100)
     5 DECLARE @tablename VARCHAR(100)
     6 DECLARE @columnnames NVARCHAR(max)
     7 DECLARE @isidentity NVARCHAR(30)
     8 DECLARE @temsql NVARCHAR(max)
     9 DECLARE @sql NVARCHAR(max)
    10 SET @fromdb = 'DatabaseFrom'
    11 SET @todb = 'DatabaseTo'
    12 
    13 IF (OBJECT_ID('#MyTempTable') IS NOT NULL)
    14 drop table #MyTempTable
    15 
    16 
    17 CREATE TABLE #MyTempTable (names varchar(500))
    18 insert into #MyTempTable
    19 SELECT name from sys.tables WHERE type='U' AND name not in (select OBJECT_NAME(parent_object_id) 'name' from sys.objects where type='F') 
    20 
    21 insert into #MyTempTable
    22 select OBJECT_NAME(parent_object_id) 'name' from sys.objects where type='F' order by object_id
    23 
    24 
    25 --游标
    26 DECLARE @itemCur CURSOR
    27 SET @itemCur = CURSOR FOR 
    28     SELECT names from #MyTempTable
    29 
    30 OPEN @itemCur
    31 FETCH NEXT FROM @itemCur INTO @tablename
    32 WHILE @@FETCH_STATUS=0
    33 
    34 BEGIN
    35     
    36     SET @sql = ''
    37 
    38     --获取表字段
    39     SET @temsql = N'
    40     BEGIN
    41     SET @columnnamesOUT =''''
    42     SELECT @columnnamesOUT = @columnnamesOUT + '','' + ''['' + name + '']''
    43     From sys.columns where object_id=OBJECT_ID(''['+@fromdb+'].dbo.'+@tablename+''')
    44     order by column_id
    45     SELECT @columnnamesOUT=substring(@columnnamesOUT,2,len(@columnnamesOUT))
    46     END
    47     '
    48     EXEC sp_executesql @temsql,N'@columnnamesOUT NVARCHAR(max) OUTPUT',@columnnamesOUT=@columnnames OUTPUT
    49 
    50     PRINT ('--'+@tablename)
    51     PRINT ('--表名 '''+@tablename+'''')
    52 
    53 
    54 
    55 
    56     --INSERT
    57     SET @sql = @sql+'SELECT * INTO ['+@todb+'].[dbo].['+@tablename+'] FROM ['+@fromdb+'].[dbo].['+@tablename+']'
    58 
    59 
    60 
    61     --返回SQL
    62     PRINT(@sql)PRINT('GO')+CHAR(13)
    63 
    64     FETCH NEXT FROM @itemCur INTO @tablename
    65 END 
    66 
    67 CLOSE @itemCur
    68 DEALLOCATE @itemCur
    69 
    70 
    71 drop table #MyTempTable
    然后拷贝消息栏的语句执行即可:
     1 (749 行受影响)
     2 
     3 (0 行受影响)
     4 --sm_idx_River_2
     5 --表名 'sm_idx_River_2'
     6 SELECT * INTO [JD_2_Back].[dbo].[sm_idx_River_2] FROM [JD_2].[dbo].[sm_idx_River_2]
     7 GO
     8 
     9 --TyphoonGustForm_1
    10 --表名 'TyphoonGustForm_1'
    11 SELECT * INTO [JD_2_Back].[dbo].[TyphoonGustForm_1] FROM [JD_2].[dbo].[TyphoonGustForm_1]
    12 GO
    13 
    14 --Interpolation_3Tier3
    15 --表名 'Interpolation_3Tier3'
    16 SELECT * INTO [JD_2_Back].[dbo].[Interpolation_3Tier3] FROM [JD_2].[dbo].[Interpolation_3Tier3]
    17 GO
    18 
    19 --YGZZPonding3_CJ
    20 --表名 'YGZZPonding3_CJ'
    21 SELECT * INTO [JD_2_Back].[dbo].[YGZZPonding3_CJ] FROM [JD_2].[dbo].[YGZZPonding3_CJ]
    22 GO
    23 
    24 --ForestDistribut_2
    25 --表名 'ForestDistribut_2'
    26 SELECT * INTO [JD_2_Back].[dbo].[ForestDistribut_2] FROM [JD_2].[dbo].[ForestDistribut_2]
    27 GO
    可能会有错误,如下所示:我们就找出了 出错的数据表了!然后在手动修改特定的错误表吧......

    最后就是删除损坏的数据库,更改新数据库名字即可。

     无奈损坏的数据库为超图映射过来的数据库(推测,超图对数据库设置了一些除表外其他的一些附加信息),通过新建数据库,然后简单的导出数据,还是无法解决(通过超图桌面版和object.net版本 无法修改数据集 )。最后只能,找出去年备份的数据库,然后看下哪些数据集更新,从损坏的数据库中慢慢更新了。。。。。。 

     
  • 相关阅读:
    JAVA8十大新特性详解
    博客主题
    nideshop小程序商城部署
    Eclipse创建Maven多模块工程Module开发(图文教程)
    将博客搬至CSDN
    腾讯开源软件镜像站上线
    python-应用OpenCV和Python进行SIFT算法的实现
    初学node.js-nodejs中实现删除用户路由
    本博客正在实验姿态捕捉,可以尝试允许摄像头运行
    博客园如何实现看板娘Live2d?来吧少年,开启新世界的大门!——live2d 博客园 个性化定制
  • 原文地址:https://www.cnblogs.com/foreveryt/p/4626113.html
Copyright © 2011-2022 走看看