2011年3月24日 星期四

MS SQL Log 修復

MS SQL Log 修復
如果遺失日誌檔

小知識: SQL恢復技術

SQL Server 資料庫檔恢復技術
SQL Server 資料庫備份有兩種方式,一種是使用BACKUP DATABASE 將資料庫檔備份出去,另外一種就是直接拷貝資料庫檔 mdf 和日誌檔ldf的方式。下面將主要討論一下後者的備份與恢復。
本文假定您能熟練使用SQL Server Enterprise Manager (SQL Server企業管理器) 和 SQL Server Quwey Analyser(SQL Server查詢分析器)。

1、正常的備份、恢復方式
正常方式下,我們要備份一個資料庫,首先要先將該資料庫從運行的資料伺服器中斷開,或者停掉整個資料庫伺服器,然後複製檔。
卸下資料庫的命令:Sp_detach_db 資料庫名
連接資料庫的命令:Sp_attach_db
或者
sp_attach_single_file_db
sp_attach_db [@dbname =] 'dbname', [@filename1 =] 'filename_n' [,…16]
sp_attach_single_file_db [@dbname =] 'dbname', [@physname =] 'physical_name'

使用此方法可以正確恢復 SQL Sever7.0 和 SQL Server 2000 的資料庫檔,要點是備份的時候一定要將 mdf 和 ldf 兩個檔都備份下來,mdf 檔是資料庫資料檔案,ldf 是資料庫日誌檔。

例子:
假設資料庫為test,其資料檔案為test_data.mdf,日誌檔為test_log.ldf。下面我們討論一下如何備份、恢復該資料庫。

卸下資料庫:

sp_detach_db 'test'

連接資料庫:

sp_attach_db 'test', 'C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_data.mdf', 'C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_log.ldf'

sp_attach_single_file_db 'test','C:\Program Files\Microsoft SQL S erver\MSSQL\Data\test_data.mdf'

2、只有mdf檔的恢復技術
由於種種原因,我們如果當時僅僅備份了 mdf 檔,那麼恢復起來就是一件很麻煩的事情了。 如果您的 mdf 檔是當前資料庫產生的,那麼很僥倖,也許你使用 sp_attach_db 或者 sp_attach_single_file_db 可以恢復資料庫,但是會出現類似下面的提示資訊設備啟動錯誤。物理檔案名 'C:\Program Files\Microsoft SQL Server\MSSQL\data\test_Log.LDF' 可能有誤。
已創建名為 'C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_log.LDF' 的新日誌檔。
但是,如果您的資料庫檔是從其他電腦上複製過來的,那麼很不幸,也許上述辦法就行不通了。你也許會得到類似下面的錯誤資訊
伺服器: 消息 1813,級別 16,狀態 2,行 1
未能打開新資料庫 'test'。CREATE DATABASE 將終止。
設備啟動錯誤。物理檔案名 'd:\test_log.LDF' 可能有誤。
怎麼辦呢?別著急,下面我們舉例說明恢復辦法。
A.我們使用默認方式建立一個供恢復使用的資料庫(如test)。可以在SQL Server Enterprise Manager裏面建立。
B.停掉資料庫伺服器。
C.將剛才生成的資料庫的日誌檔test_log.ldf刪除,用要恢復的資料庫mdf檔覆蓋剛才生成的資料庫資料檔案test_data.mdf。
D.啟動資料庫伺服器。此時會看到資料庫test的狀態為“置疑”。這時候不能對此資料庫進行任何操作。
E.設置資料庫允許直接作業系統表。此操作可以在SQL Server Enterprise
Manager裏面選擇資料庫伺服器,按右鍵,選擇“屬性”,在“伺服器設置”頁面中將“允許對系統目錄直接修改”一項選中。也可以使用如下語句來實現。

use master
go
sp_configure 'allow updates',1
go
reconfigure with override
go

F.設置test為緊急修復模式

update sysdatabases set status=-32768 where dbid=DB_ID('test')

此時可以在SQL Server Enterprise
Manager裏面看到該資料庫處於“唯讀\置疑\脫機\緊急模式”可以看到資料庫裏面的表,但是僅僅有系統表

G.下面執行真正的恢復操作,重建資料庫日誌檔

dbcc rebuild_log('test','C:\Program Files\Microsoft SQL Server\MSSQL\Data\test_log.ldf')

執行過程中,如果遇到下列提示資訊:
伺服器: 消息 5030,級別 16,狀態 1,行 1
未能排它地鎖定資料庫以執行該操作。
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯繫。
說明您的其他程式正在使用該資料庫,如果剛才您在F步驟中使用SQL Server Enterprise
Manager打開了test庫的系統表,那麼退出SQL Server Enterprise Manager就可以了。
正確執行完成的提示應該類似於:
警告: 資料庫 'test' 的日誌已重建。已失去事務的一致性。應運行 DBCC CHECKDB
以驗證物理一致性。將必須重置資料庫選項,並且可能需要刪除多餘的日誌檔。
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯繫。
此時打開在SQL Server Enterprise Manager裏面會看到資料庫的狀態為“只供DBO使用”。此時可以訪問資料庫裏面的用戶表了。
H.驗證資料庫一致性(可省略)

dbcc checkdb('test')

一般執行結果如下:
CHECKDB 發現了 0 個分配錯誤和 0 個一致性錯誤(在資料庫 'test' 中)。
DBCC 執行完畢。如果 DBCC 輸出了錯誤資訊,請與系統管理員聯繫。
I.設置資料庫為正常狀態

sp_dboption 'test','dbo use only','false'

如果沒有出錯,那麼恭喜,現在就可以正常的使用恢復後的資料庫啦。
J.最後一步,我們要將步驟E中設置的“允許對系統目錄直接修改”一項恢復。因為平時直接作業系統表是一件比較危險的事情。當然,我們可以在SQL Server
Enterprise Manager裏面恢復,也可以使用如下語句完成

sp_configure 'allow updates',0
go
reconfigure with override
go

INF: 壓縮交易記錄檔在 SQL Server 2000 與 DBCC SHRINKFILE
檢視此文章適用的產品。
注意:本文是不經人為參與的自動機器翻譯系統翻譯完成。這些文章是Microsoft為非英語系國家使用者所提供,讓使用者可以了解文章的內容。Microsoft 不保證翻譯的語言品質也不對由於內容的錯譯或客戶針對內容使用所發生的任何直接或間接可能的問題負責。
文章編號 : 272318
上次校閱 : 2003年11月6日
版次 : 3.0
在此頁中

結論

其他相關資訊

REFERENCES
結論
壓縮記錄檔在 SQL Server 2000 是不再延遲的作業。 壓縮作業嘗試立即壓縮檔案。 不過在某些情況下可能需要, 以執行其他動作之前是記錄檔壓縮至所需的大小。

其他相關資訊
藉由移除多個虛擬記錄檔, 它可以嘗試重新達到目標大小, 在執行 DBCC SHRINKFILE 時, SQL Server 2000 壓縮記錄檔。 如果無法達到目標檔案大小, SQL Server 在最後一個虛擬記錄檔中放入空的記錄檔項目, 直到填滿虛擬記錄檔並將標頭的記錄檔移到開頭的檔案。 下列動作則需要以完成的交易記錄檔壓縮: 1. 您必須執行 BACKUP LOG 陳述式來釋放空間藉由移除非現用的記錄檔部分。
2. 您必須執行 DBCC SHRINKFILE 再次具有所需的目標大小, 直到記錄檔壓縮成目標大小。
下列範例示範這與 pubs 資料庫並嘗試 pubs_log 檔壓縮成 2 MB:

1. 執行此程式碼:
DBCC SHRINKFILE(pubs_log, 2)
請注意 : 如果無法達到目標大小, 請繼續進行下一個步驟

2. 如果您是否要保留的交易記錄檔備份截斷交易記錄檔並執行這個程式碼。 您的交易記錄檔備份順序 Truncate_only 失效。 在您執行備份記錄檔與 truncate_only 才會完整的您的資料庫備份:
BACKUP LOG pubs WITH TRUNCATE_ONLY
- 或 -
如果您要保留您的交易記錄檔的備份並讓您的交易記錄檔備份順序保持完整執行此程式碼。 請參閱 SQL Server 線上叢書 》 主題 < BACKUP " 如需詳細資訊: BACKUP LOG pubs TO pubslogbackup

3. 執行此程式碼:
DBCC SHRINKFILE(pubs_log,2)

已將交易記錄檔現在已縮小為目標大小。

REFERENCES
如需詳細資訊, 請參閱 SQL Server 2000 線上叢書 》 中的 壓縮交易記錄檔 以及 DBCC SHRINKFILE 主題。

如需有關壓縮交易記錄檔在 SQL Server 7.0, 請按一下下面文件編號, 檢視 「 Microsoft 知識庫 」 中的文件中的文件:
256650 (http://support.microsoft.com/kb/256650/EN-US/) INF: 如何壓縮 SQL Server 交易記錄檔

資料來源:http://support.microsoft.com/kb/272318/
INF: 如何將 SQL Server 交易記錄檔壓縮:http://support.microsoft.com/kb/256650/

SET NOCOUNT ON
   DECLARE @LogicalFileName sysname,
           @MaxMinutes INT,
           @NewSize INT
   -- Your criteria here.
   USE     mc232_150_jt012              -- This is the name of the database    for which the log will be shrunk.
   SELECT  @LogicalFileName = 'p2db_log',  -- Use sp_helpfile to identify the logical file name that you want to shrink.
           @MaxMinutes = 12,               -- Limit on time allowed to wrap log.
           @NewSize = 500                  -- in MB
   -- Setup / initialize
   DECLARE @OriginalSize int
   SELECT @OriginalSize = size -- in 8K pages
     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)
   -- Wrap log and truncate it.
   DECLARE @Counter   INT,
           @StartTime DATETIME,
           @TruncLog  VARCHAR(255)
   SELECT  @StartTime = GETDATE(),
           @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY'
   -- Try an initial shrink.
   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)  -- the log has not shrunk   
         AND (@OriginalSize * 8 /1024) > @NewSize  -- The value passed in for new size is smaller than the current size.
     BEGIN -- Outer loop.
       SELECT @Counter = 0
       WHILE  ((@Counter < @OriginalSize / 16) AND (@Counter < 50000))
         BEGIN -- update
           INSERT DummyTrans VALUES ('Fill Log')  -- Because it is a char field it inserts 8000 bytes.
           DELETE DummyTrans
           SELECT @Counter = @Counter + 1
         END   -- update
       EXEC (@TruncLog)  -- See if a trunc of the log shrinks it.
     END   -- outer loop
   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
   PRINT '*** Perform a full database backup ***'
SET NOCOUNT OFF

當SQL資料庫日誌文件已滿,或者日誌很大,怎麼辦?

先提供一種複雜的方法壓縮日誌及資料庫文件如下:

1.清空日誌
DUMP  TRANSACTION  庫名  WITH  NO_LOG
2.截斷事務日誌:
BACKUP LOG 資料庫名 WITH NO_LOG
3.收縮資料庫文件(如果不壓縮,資料庫的文件不會減小
企業管理器--右鍵你要壓縮的資料庫--所有任務--收縮資料庫--收縮文件
--選擇日誌文件--在收縮方式裡選擇收縮至XXM,這裡會給出一個允許收縮到的最小M數,直接輸入這個數,確定就可以了
--選擇資料文件--在收縮方式裡選擇收縮至XXM,這裡會給出一個允許收縮到的最小M數,直接輸入這個數,確定就可以了
也可以用SQL語句來完成
--收縮資料庫
DBCC SHRINKDATABASE(客戶資料)
--收縮指定資料文件,1是文件號,可以通過這個語句查詢到:select * from sysfiles
DBCC SHRINKFILE(1)
4.為了最大化的縮小日誌文件(如果是sql 7.0,這步只能在查詢分析器中進行)
a.分離資料庫:
企業管理器--伺服器--資料庫--右鍵--分離資料庫
b.在我的電腦中刪除LOG文件
c.附加資料庫:
企業管理器--伺服器--資料庫--右鍵--附加資料庫
此法將生成新的LOG,大小只有500多K
或用代碼:
下面的示例分離 pubs,然後將 pubs 中的一個文件附加到當前伺服器。
a.分離
exec sp_detach_db @dbname = 'pubs'
b.刪除日誌文件
c.再附加
exec sp_attach_single_file_db @dbname = 'pubs',
@physname = 'c:\Program Files\Microsoft SQL Server\MSSQL\Data\pubs.mdf'
5.為了以後能自動收縮,做如下設置:
企業管理器--伺服器--右鍵資料庫--屬性--選項--選擇"自動收縮"
--SQL語句設置方式:
exec sp_dboption '資料庫名', 'autoshrink', 'TRUE'
6.如果想以後不讓它日誌增長得太大
企業管理器--伺服器--右鍵資料庫--屬性--事務日誌
--將文件增長限制為xM(x是你允許的最大資料文件大小)
--SQL語句的設置方式:
alter database 資料庫名 modify file(name=邏輯文件名,maxsize=20)
特別注意:
請按步驟進行,未進行前面的步驟,請不要做後面的步驟
否則可能損壞你的資料庫.
一般不建議做第4,6兩步
第4步不安全,有可能損壞資料庫或丟失資料
第6步如果日誌達到上限,則以後的資料庫處理會失敗,在清理日誌後才能恢復.

另外提供一種更簡單的方法,本人屢試不爽,建議大家使用。
更簡單的方法:
1。右建資料庫屬性窗口--故障還原模型--設為簡單
2。右建資料庫所有任務--收縮資料庫
3。右建資料庫屬性窗口--故障還原模型--設為大容量日誌記錄

沒有留言: