Impostare la modalità di ripristino semplice e ridurre i file di registro per tutti i database creati dall'utente


8

Spero che tu possa indicarmi la giusta direzione. Non sono un utente frequente di T-SQL, ma ho fatto un po 'di ricerche su Google e ho trovato lo script di seguito. Ho corretto un po 'la sceneggiatura.

Voglio che la sceneggiatura:

  1. Per selezionare tutti i database, tranne i DB di sistema.
  2. Per impostare il recupero su semplice.
  3. Ridurre i file di registro per ogni db (.ldf), ad eccezione del db di sistema

Il copione:

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

Perché perché perché? Inoltre qual è "la giusta direzione"? La sceneggiatura non funziona? Se é cosi, come? Hai ricevuto un messaggio di errore? Che cos'è? Probabilmente è necessario un comando USE nell'ultimo blocco. Ma ancora: perché, perché, perché?
Aaron Bertrand

Perché i file .ldf occupano il 70% dello spazio su disco sul server. Ma se conosci un modo migliore, per favore illuminami. Non so se lo script funziona, non posso semplicemente eseguirlo. Devo essere sicuro che funzioni per primo, dal momento che è un ambiente di produzione.
Arviddk,

Non hai un ambiente di sviluppo o test in cui puoi testarlo? Francamente non prenderei nulla da qui, indipendentemente da chi lo ha scritto, e applicarlo alla produzione basandosi solo sulle assicurazioni degli estranei su Internet ...
Aaron Bertrand

@Arviddk Sai quali sono le conseguenze della modifica del modello di recupero da FULL / BULK LOGGED a SEMPLICE? Se sei a conoscenza, vai avanti e fallo.
BuahahaXD

Volevo solo commentare il motivo per i futuri lettori che potrebbero voler fare la stessa cosa. In passato eseguivamo backup SQL completi con backup dei registri delle transazioni. Da allora siamo passati all'utilizzo di Dell AppAssure per eseguire backup che ci mettono in un luogo in cui non abbiamo bisogno di backup del registro delle transazioni. Ora ci rimangono centinaia di database su più server ancora impostati al massimo con terabyte di file LDF senza motivo. Ciò influisce su backup / ripristini, nonché su altre cose che lo circondano, la replica e così via.
Thorin,

Risposte:


13

Utilizzare lo script per ridurre i file di registro di tutti i database diversi dai DB di sistema.

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

All'inizio ho pensato che l'esecuzione ------...avrebbe comportato un errore, ma l'evidenziazione della sintassi mi ha dato un suggerimento su cosa sarebbe effettivamente accaduto. ! Neat
ta.speot.is il

Grazie, lo proverò nel nostro ambiente di sviluppo e spingerò a prod
Thorin il

È necessario aggiungere "DBCC SHRINKFILE ('' '+ @ LogicalFileName +' _ Log '', 10) GO" - altrimenti il ​​database dei registri non verrà ridotto.
Andreas Rehm,

5

Ho sempre avuto una tale avversione per i cursori, che ho scritto questo per poterlo capire meglio. È totalmente basato sulla risposta di AA.SC (grazie a proposito), semplicemente in un modo che penso. Se questo va bene per quello che pensano gli altri, allora fantastico. Nota, in seguito non l'ho riportato in modalità di recupero completo.

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 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.