Establezca un modo de recuperación simple y reduzca los archivos de registro para todas las bases de datos creadas por el usuario

8

Espero que puedas señalarme en la dirección correcta. No soy un usuario frecuente de T-SQL, pero busqué en Google y encontré el script a continuación. Corregí un poco el guión.

Quiero que el guión:

  1. Para seleccionar todas las bases de datos, excepto las bases de datos del sistema.
  2. Para establecer la recuperación a simple.
  3. Para reducir los archivos de registro para cada db (.ldf), excepto el sistema db

La secuencia de comandos:

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
fuente
¿Por qué, por qué, por qué? Además, ¿cuál es "la dirección correcta"? ¿El guión no funciona? ¿Si es así, cómo? ¿Recibe un mensaje de error? ¿Qué es? Probablemente necesite un comando USE en el último bloque. Pero de nuevo: ¿Por qué, por qué, por qué?
Aaron Bertrand
Porque los archivos .ldf ocupan el 70% del espacio en disco en el servidor. Pero si sabes de una mejor manera, por favor, ilumíname. No sé si el script funciona, no puedo ejecutarlo. Tengo que estar seguro de que funciona primero, ya que es un entorno de producción.
Arviddk
¿No tienes un entorno de desarrollo o prueba donde puedas probar esto? Francamente, no tomaría nada de aquí, independientemente de quién lo escribió, y lo aplicaría a la producción basado solo en las seguridades de extraños en Internet ...
Aaron Bertrand
@Arviddk ¿Sabe cuáles son las consecuencias de cambiar el modelo de recuperación de FULL / BULK LOGGED a SIMPLE? Si es consciente, continúe y haga eso.
BuahahaXD
Solo quería comentar sobre el por qué para futuros lectores que pueden estar buscando hacer lo mismo. Solíamos hacer copias de seguridad completas de SQL con copias de seguridad de registros de transacciones. Desde entonces, cambiamos a usar Dell AppAssure para hacer copias de seguridad, lo que nos coloca en un lugar donde no necesitamos copias de seguridad del registro de transacciones. Ahora nos quedan cientos de bases de datos en varios servidores aún configuradas con terabytes de archivos LDF sin ningún motivo. Esto afecta a las copias de seguridad / restauraciones, así como a otras cosas que rodean eso, la replicación y demás.
Thorin

Respuestas:

13

Use Script para reducir los archivos de registro de todas las bases de datos que no sean las bases de datos del 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
AA.SC
fuente
Al principio pensé que la ejecución ------...provocaría un error, pero el resaltado de sintaxis me dio una pista sobre lo que realmente sucedería. ¡Ordenado!
ta.speot.is
Gracias, voy a probar esto en nuestro entorno de desarrollo y presionar para probar
Thorin
Debe agregar "DBCC SHRINKFILE ('' '+ @ LogicalFileName +' _ Log '', 10) GO"; de lo contrario, la base de datos de registro no se reducirá.
Andreas Rehm
5

Siempre tuve tanta aversión a los cursores, que escribí esto porque puedo entenderlo mejor. Está totalmente basado en la respuesta de AA.SC (gracias por cierto), solo de una manera que creo. Si esto coincide con lo que otros piensan, entonces genial. Tenga en cuenta que no lo puse nuevamente en modo de recuperación completa después.

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
fuente