記錄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版本 無法修改數據集 )。最后只能,找出去年備份的數據庫,然后看下哪些數據集更新,從損壞的數據庫中慢慢更新了。。。。。。 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM