2010-10-05 50 views
-1

嗨我在每週維護過程中使用此腳本,建議最佳方法/腳本來執行收縮日誌。目前,我得到一個錯誤與下面的腳本收縮日誌SQL2008中的所有用戶數據庫

declare @s nvarchar(4000) 
set @s= ' 
     if ''?'' not in (''tempdb'',''master'',''model'',''msdb'') 
     begin 
      use [?] 
      Alter database [?] SET Recovery simple 
     end ' 

exec sp_msforeachdb @s 
set @s= ' 
     if ''?'' not in (''tempdb'',''master'',''model'',''msdb'') 
     begin  
      use [?] 
      Declare @LogFileLogicalName sysname 
      select @LogFileLogicalName=Name from sys.database_files where Type=1 
      DBCC Shrinkfile(@LogFileLogicalName,1) 
     end' 
exec sp_msforeachdb @s 

錯誤說明:

ShrinkLog Execute SQL Task Description: Executing the query "declare @s nvarchar(4000) set @s= ' ..." failed with the following error: "Option 'RECOVERY' cannot be set in database 'tempdb'. Cannot shrink log file 2 (DBServices_Log) because total number of logical log files cannot be fewer than 2. DBCC execution completed. If DBCC printed error messages, contact your system administrator.

注:我在我的劇本避免tempdb數據庫(所有系統DB),但錯誤消息顯示tempdb的?

+0

當您在普通查詢窗口而不是計劃作業中手動運行時,是否出現錯誤? – Pondlife 2010-10-06 11:27:55

+0

它計劃運行通過SQL ServerAgent作業 – rmdussa 2010-10-06 22:26:29

回答

3

這可能是我在過去一年中看到的最差的維護腳本。一個維護腳本,每週打破日誌鏈,並使數據庫無法恢復?我的天啊。更不用說,縮短日誌維護任務的簡單前提是錯誤的。如果數據庫日誌已經增長到一定的大小,則需要這個大小。更頻繁地安排日誌備份以防止這種情況發生,但不要日程安排日誌縮減操作。

+0

我appriciate您的建議,想知道這個腳本有什麼問題。 – rmdussa 2010-10-07 00:48:55

+1

有兩件事情是錯誤的:1)'改變數據庫[?] SET Recovery simple'會在任何數據庫的*日誌鏈中*不*在簡單的恢復中。 2)腳本的前提是錯誤的,你需要定期收縮日誌。經常進行日誌備份(如果尚未處於簡單恢復模式),日誌會保持較小。收縮是一種非凡的操作,只在特殊場合進行,**從不**在定期的定期維護。 – 2010-10-07 01:07:26

+0

請查看註釋並回復, – rmdussa 2010-10-07 02:05:23

0

通過使用exec語句更改數據庫恢復模型,可以避免5058錯誤。以下腳本會將每個用戶數據庫設置爲簡單恢復模式。 (它使用Jimmy's answer檢測系統數據庫。)

exec sp_msforeachdb 'if exists (select name from sys.databases d where case when d.name in (''master'',''model'',''msdb'',''tempdb'') then 1 else d.is_distributor end = 0 
    and name = ''?'' and recovery_model_desc != ''SIMPLE'') 
begin 
    declare @previousRecoveryModel varchar(100) = (select recovery_model_desc from sys.databases where name = ''?''); 
    print ''Changing recovery model for ? from '' + @previousRecoveryModel + '' to SIMPLE.''; 
    use master; 
    -- Using exec avoids a compile-time 5058 error about tempdb, which is a branch that will never be executed in this code. 
    exec (''alter database [?] set recovery simple''); 
end'; 

那麼您將無法獲得有關tempdb中的編譯時錯誤,因爲exec語句將編譯它與已經取代數據庫名變量聲明。