您好我在每周维护过程中使用此脚本,建议使用最佳方法/脚本来进行收缩日志。目前我正在使用以下脚本收到错误
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执行SQL任务描述:执行查询“declare @s nvarchar(4000)set @ s ='...”失败,出现以下错误:“无法在数据库'tempdb'中设置选项'RECOVERY'。不能收缩日志文件2(DBServices_Log)因为逻辑日志文件的总数不能少于2. DBCC执行完成。如果DBCC打印出错误消息,请联系您的系统管理员。
注意:我在脚本中避免使用tempdb(所有系统数据库),但错误消息显示tempdb?
答案 0 :(得分:3)
这可能是我去年见过的最糟糕的维护脚本。每周打破日志链并使数据库无法恢复的维护脚本?我的天啊。更不用说缩小日志维护任务的简单前提是错误的。如果数据库日志已增长到某个大小,则需要该大小。更频繁地安排日志备份以防止这种情况,但不要安排日志缩减操作。
答案 1 :(得分: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语句将使用已经替换的数据库名称变量编译它的语句。