2010-10-05 54 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语句将编译它与已经取代数据库名变量声明。