为所有用户创建的数据库设置简单的恢复模式并收缩日志文件


8

希望您能指出正确的方向。我不是T-SQL的经常用户,但是我做了一些Google搜索,并在下面找到了脚本。我纠正了一下脚本。

我希望脚本执行以下操作:

  1. 选择除系统数据库之外的所有数据库。
  2. 要将恢复设置为简单。
  3. 收缩每个db(.ldf)的日志文件,系统db除外

剧本:

USE MASTER
declare
@isql varchar(2000),
@dbname varchar(64)

declare c1 cursor for select name from master..sysdatabases where name not in ('master','model','msdb','tempdb','ReportServer','ReportServerTempDB')
open c1
fetch next from c1 into @dbname
While @@fetch_status <> -1
    begin
    select @isql = 'ALTER DATABASE @dbname SET RECOVERY SIMPLE'
    select @isql = replace(@isql,'@dbname',@dbname)
    print @isql
    exec(@isql)
    select @isql='USE @dbname checkpoint'
    select @isql = replace(@isql,'@dbname',@dbname)
    print @isql
    exec(@isql)
    select @isql='DBCC SHRINKFILE @dbname.ldf'
    select @isql = replace(@isql,'@dbname',@dbname)
    print @isql
    exec(@isql)

    fetch next from c1 into @dbname
    end
close c1
deallocate c1

为什么,为什么,为什么?还有什么是“正确的方向”?脚本不起作用吗?如果是这样,怎么办?您是否收到错误消息?它是什么?最后一块可能需要USE命令。但是又一次:为什么,为什么,为什么?
亚伦·伯特兰

因为.ldf文件占用了服务器上70%的磁盘空间。但是,如果您知道更好的方法,请赐教。我不知道该脚本是否有效,我无法运行它。我必须确保它首先可以工作,因为它是生产环境。
Arviddk

您没有可以测试此环境的开发或测试环境?坦白说,我不会从这里取走任何东西,无论是谁写的,都只能基于互联网上对陌生人的保证将其应用于生产……
Aaron Bertrand

@Arviddk您知道将恢复模型从“已记录全部/批量记录”更改为“简单”会带来什么后果吗?如果您知道,请继续执行此操作。
BuahahaXD

我只是想评论为什么将来可能想要做同样事情的读者。我们曾经使用事务日志备份来进行完整的SQL备份。此后,我们转而使用Dell AppAssure进行备份,这使我们处在不需要事务日志备份的地方。现在,我们剩下的数百个跨多个服务器的数据库仍然无缘无故地设置为TB级的LDF文件。这会影响备份/还原以及与此相关的其他事情,复制等。
索林2016年

Answers:


13

使用脚本收缩除系统DB以外的所有数据库的日志文件。

USE MASTER   
GO    
SET QUOTED_IDENTIFIER ON  
GO  
SET ARITHABORT ON  
GO  

DECLARE @DBName NVARCHAR(255),@LogicalFileName NVARCHAR(255),@DBRecoveryDesc Varchar(200)  

DECLARE DatabaseList CURSOR   
FOR   
SELECT name,recovery_model_desc  
FROM sys.databases  
WHERE state_desc = 'ONLINE'  
AND is_read_only = 0  
and database_id>4  
ORDER BY name  

OPEN DatabaseList  
FETCH NEXT FROM DatabaseList INTO @DBName,@DBRecoveryDesc  
WHILE @@FETCH_STATUS = 0     
BEGIN   

SET @LogicalFileName=(SELECT top 1 name FROM sys.master_files AS mf WHERE DB_NAME(database_id)=@DBName and type_desc='LOG')  

If @DBRecoveryDesc='Full'  
Begin  
     Print('Use ['+@DBName+'] 
            GO  

           ALTER DATABASE ['+@DBName+'] SET RECOVERY SIMPLE WITH NO_WAIT
           GO   

            DBCC SHRINKFILE ('''+@LogicalFileName+''',10)  
            GO  

            ALTER DATABASE ['+@DBName+'] SET RECOVERY FULL WITH  NO_WAIT
            GO ')  
Print '----------------------------------------------------------- '  
END  

If @DBRecoveryDesc='Simple'  
Begin   
     Print('Use ['+@DBName+']  
            GO  

            DBCC SHRINKFILE ('''+@LogicalFileName+''',10)    
            GO    
 ')  
Print '----------------------------------------------------------- '

END

         FETCH NEXT FROM DatabaseList INTO @DBName,@DBRecoveryDesc
      END  
CLOSE DatabaseList  
DEALLOCATE DatabaseList

起初我以为执行------...会导致错误,但是语法高亮显示了实际情况。整齐!
ta.speot。是2016年

谢谢,我将在我们的开发环境中尝试此产品,并推向正式生产
Thorin

您应该添加“ DBCC SHRINKFILE('''+ @ LogicalFileName +'_ Log'',10)GO“-否则将不会缩小日志数据库。
安德烈亚斯·雷姆

5

我一直很讨厌游标,所以我写了这是为了更好地理解它。它完全基于AA.SC的回答(顺便谢谢您),只是以我认为的方式提出。如果这与别人的想法相吻合,那就太好了。请注意,不过之后我没有将其恢复为完全恢复模式。

SELECT 
'--', d.name dbName, d.recovery_model, d.recovery_model_desc , mf.name LogicalFileName,
'
use [' + d.name + ']

if(' + cast(d.recovery_model as varchar(5)) + ' = 1)
BEGIN
    ALTER DATABASE ['+ d.name +'] SET RECOVERY SIMPLE WITH NO_WAIT
END
GO 
DBCC SHRINKFILE (''' + mf.name  +''',10)  
GO  
'
FROM sys.databases d
join sys.master_files mf
    on d.database_id = mf.database_id
    and mf.type_desc = 'LOG' 
WHERE d.state_desc = 'ONLINE'  
AND d.is_read_only = 0  
and d.database_id > 4 
--and d.recovery_model = 1
ORDER BY d.name 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.