1. 程式人生 > >SQL Server 2008無日誌檔案附加資料庫

SQL Server 2008無日誌檔案附加資料庫

我們的“DBA”晚上執行了一個涉及使用者的操作,結果執行資料量太大,導致sql server存放日誌的磁碟空間不足,第二天早起發現論壇出現問題,不能發帖。收縮日誌不見效果的情況下,和其主管商議決定直接刪除日誌檔案.ldf 。沒有進一步驗證自己的方案,就付諸實施。

1、停服務;

2、刪除日誌檔案(直接物理刪除了:(;

3、再啟動服務,

4、原設想是可以直接建立日誌檔案,或者通過手工建立,未果;

    4.1、把資料庫離線處理,再做分離操作

    4.2、新建立一個空的同名數據庫,停掉服務,把新庫的mdf檔案刪除,然後把原庫的mdf檔案覆蓋,再啟動服務,未果

     4.3、接4.2,建立同名空庫後,分離,覆蓋,再附加,未果

我介入後:

1、問明情況後,依據自己原來的操作經驗,知道這種情況肯定是有辦法的,只要資料檔案沒有損壞;

2、上網搜尋,找到一個

CREATE DATABASE DBname
ON (FILENAME = 'D:\SalesData\archdat1.mdf')
FOR ATTACH_REBUILD_LOG ;

在本地伺服器上新建立資料庫,然後分離、刪除ldf檔案、然後執行上述程式碼,成功。

到生產環境上執行,報錯,失敗。前面的操作可能過多,mdf檔案的資料可能有損壞,報錯,錯誤資訊忘記了

公司網站運營兩年多了,日誌檔案超級大,在重灌系統的時候,為了省事,就沒有備份日誌檔案,而且是沒有分離就把日誌檔案給刪掉了(下次一定要記得先分離再刪日誌檔案)。結果造成資料庫怎麼都附加不上。出現錯誤。

解決辦法:

1、新建一個同名數據庫。

2、停止資料庫服務,覆蓋新建的資料庫主檔案(小技巧:最好放在同一個磁盤裡面,把新建的資料庫主檔案刪掉或移開,再把要恢復的資料庫主檔案剪下過去,這樣就可以節省時間。)

3、啟動資料庫服務,資料庫變為置疑或可疑狀態。然後在查詢分析器中執行:

alter database 無日誌檔案的資料庫名稱 set emergency

設定為緊急狀態。

4、再執行:

alter database 無日誌檔案的資料庫名稱 set single_user

或者:

Sp_dboption '無日誌檔案的資料庫名稱', 'single user', 'true'

設定為單使用者模式。

5、檢查並重建日誌檔案,執行:

dbcc checkdb('無日誌檔案的資料庫名稱',REPAIR_ALLOW_DATA_LOSS)

這個時間比較長。耐心等待!如果有錯誤提示,再執行:

dbcc checkdb('無日誌檔案的資料庫名稱',REPAIR_REBUILD)

進行修復。如果沒有錯誤,可以跳過。

6、恢復成多使用者模式

alter database 無日誌檔案的資料庫名稱 set multi_user

或者:

Sp_dboption '無日誌檔案的資料庫名稱', 'single user', 'false'

重新整理資料庫,你就可以看到已經修復好的資料庫了。

我是如此修復,至於網上還有很多修復方法,我試過,沒有成功。通過多方組合得到這個方法。可能也不是資料庫的每一個版本都適用,如果你用過後,不行,希望能留言,讓我們能共同討論,共同進步!

縮小 SQL Server 資料庫日誌檔案 2010-12-20 07:05
-- 縮小SQL Server資料庫日誌檔案
-- 修改其中的3個引數(資料庫名,日誌檔名,和目標日誌檔案的大小)

Set NoCount On
Declare @LogicalFileName sysname
Declare @MaxMinutes Int
Declare @NewSize Int

Use mm -- 要操作的資料庫名
Select @LogicalFileName = 'mm_log' -- 日誌檔名
Select @MaxMinutes = 10 -- Limit On Time allowed To Wrap Log.
Select @NewSize = 8 -- 你想設定的日誌檔案的大小(M)

-- Setup / initialize
Declare @OriginalSize Int

Select @OriginalSize = Size
From sysfiles
Where Name = @LogicalFileName

Select 'Original Size of ' + db_name() + ' LOG is ' +
CONVERT(Varchar(30),@OriginalSize) + ' 8K pages or ' +
CONVERT(Varchar(30),(@OriginalSize*8/1024)) + 'MB'
From sysfiles
Where Name = @LogicalFileName

Create Table DummyTrans (DummyColumn Char (8000) Not Null)
Declare @Counter Int,
@StartTime Datetime,
@TruncLog Varchar(255)
Select @StartTime = GETDATE(),
@TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY'
DBCC SHRINKFILE (@LogicalFileName, @NewSize)
Exec (@TruncLog)

-- Wrap the Log If necessary.
While @MaxMinutes > DATEDIFF(mi, @StartTime, GETDATE()) -- Time has Not expired
And @OriginalSize = (Select Size From sysfiles Where Name = @LogicalFileName)
And (@OriginalSize * 8 /1024) > @NewSize
Begin -- Outer Loop.
Select @Counter = 0
While ((@Counter < @OriginalSize / 16)
And (@Counter < 50000))
Begin -- Update
Insert DummyTrans Values ('Fill Log')
Delete DummyTrans
Select @Counter = @Counter + 1
End
Exec (@TruncLog)
End

Select 'Final Size of ' + db_name() + ' LOG is ' +
CONVERT(Varchar(30),Size) + ' 8K pages or ' +
CONVERT(Varchar(30),(Size*8/1024)) + 'MB'
From sysfiles
Where Name = @LogicalFileName

Drop Table DummyTrans

Set NoCount Off