Legen Sie den einfachen Wiederherstellungsmodus fest und verkleinern Sie die Protokolldateien für alle vom Benutzer erstellten Datenbanken

8

Ich hoffe, Sie können mich in die richtige Richtung weisen. Ich bin kein häufiger Benutzer von T-SQL, habe aber etwas gegoogelt und das folgende Skript gefunden. Ich habe das Skript etwas korrigiert.

Ich möchte, dass das Skript:

  1. Auswählen aller Datenbanken mit Ausnahme der System-DBs.
  2. Wiederherstellung auf einfach setzen.
  3. So verkleinern Sie die Protokolldateien für jede Datenbank (.ldf) mit Ausnahme der Systemdatenbank

Das Skript:

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
Arviddk
quelle
Warum, warum, warum? Auch was ist "die richtige Richtung"? Funktioniert das Skript nicht? Wenn das so ist, wie? Erhalten Sie eine Fehlermeldung? Was ist es? Benötigen Sie wahrscheinlich einen USE-Befehl im letzten Block. Aber nochmal: Warum, warum, warum?
Aaron Bertrand
Weil die .ldf-Dateien 70% des Speicherplatzes auf dem Server beanspruchen. Aber wenn Sie einen besseren Weg kennen, klären Sie mich bitte auf. Ich weiß nicht, ob das Skript funktioniert, ich kann es nicht einfach ausführen. Ich muss sicher sein, dass es zuerst funktioniert, da es sich um eine Produktionsumgebung handelt.
Arviddk
Sie haben keine Entwickler- oder Testumgebung, in der Sie dies testen können? Ehrlich gesagt würde ich nichts von hier nehmen, unabhängig davon, wer es geschrieben hat, und es auf die Produktion anwenden, die nur auf den Zusicherungen von Fremden im Internet basiert ...
Aaron Bertrand
@Arviddk Wissen Sie, welche Konsequenzen die Änderung des Wiederherstellungsmodells von FULL / BULK LOGGED auf SIMPLE hat? Wenn Sie sich bewusst sind, machen Sie das einfach.
BuahahaXD
Ich wollte nur das Warum für zukünftige Leser kommentieren, die vielleicht das Gleiche tun möchten. Früher haben wir vollständige SQL-Sicherungen mit Transaktionsprotokollsicherungen durchgeführt. Seitdem haben wir auf Dell AppAssure umgestellt, um Sicherungen durchzuführen, sodass wir keine Transaktionsprotokollsicherungen benötigen. Jetzt stehen uns Hunderte von Datenbanken auf mehreren Servern zur Verfügung, die ohne Grund immer noch mit Terabyte an LDF-Dateien voll sind. Dies betrifft Backups / Wiederherstellungen sowie andere Dinge, die das betreffen, Replikation und dergleichen.
Thorin

Antworten:

13

Verwenden Sie Script, um Protokolldateien aller Datenbanken außer den System-DBs zu verkleinern.

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
AA.SC
quelle
Zuerst dachte ich, das Ausführen ------...würde zu einem Fehler führen, aber das Hervorheben der Syntax gab mir einen Hinweis darauf, was tatsächlich passieren würde. Ordentlich!
ta.speot.is
Vielen Dank, ich werde dies in unserer Entwicklungsumgebung ausprobieren und auf Prod
Thorin
Sie sollten "DBCC SHRINKFILE ('' '+ @ LogicalFileName +' _ Log '', 10) GO" hinzufügen - andernfalls wird die Protokolldatenbank nicht verkleinert.
Andreas Rehm
5

Ich hatte immer eine solche Abneigung gegen Cursor, dass ich dies schrieb, weil ich es besser verstehen kann. Es basiert vollständig auf der Antwort von AA.SC (übrigens danke), nur so ausgedrückt, wie ich denke. Wenn dies mit dem übereinstimmt, was andere denken, dann großartig. Beachten Sie, dass ich es danach nicht wieder in den vollständigen Wiederherstellungsmodus versetzt habe.

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 
Mark Rullo
quelle