Dándole vueltas a lo que escribí en el post anterior se me ocurrió que podía crear un script para reducir el log de transacciones de todas las bases de datos (en SQL Server 2005 y superior), exceptuando aquellas que son del propio sistema.
El algoritmo se basa en los pasos siguientes:
- Recorrer todas las bases de datos que no son de sistema y que tienen el modelo de recuperación en completo o registro de copias masivas (quedan almacenadas en la variable de tabla @tblBD).
- Poner las bases de datos que cumplen las condiciones anteriores en modelo de recuperación simple.
- Buscar los ficheros que almacenan los registros de transacciones para cada base de datos (quedan almacenados en la tabla temporal #tblLog).
- Reducir el espacio de cada uno de los ficheros detectados en el paso anterior (mediante la instrucción DBCC_SHRINKFILE)
- Poner el modelo de recuperación de la base de datos al estado original (completo o registro de copias masivas).
Así que me puse manos a la obra, y aquí os lo dejo:
DECLARE @tblBD TABLE
(
IDAux SMALLINT IDENTITY(1,1),
BDID INT,
BDName VARCHAR(4000),
RecoveryModel SMALLINT
)
CREATE TABLE #tblLog
(
IDRowLog SMALLINT IDENTITY (1,1),
LogFilename VARCHAR(4000)
)
DECLARE @intRecoveryModel SMALLINT
DECLARE @intNumTotalBD SMALLINT
DECLARE @intContBD SMALLINT=1
DECLARE @intBDID INT
DECLARE @strBDName VARCHAR(4000)
DECLARE @strSQL AS NVARCHAR(4000)
INSERT INTO @tblBD
SELECT database_id,
name,
recovery_model
FROM sys.databases
WHERE NAME NOT IN ('master','tempdb','model','msdb')
AND recovery_model IN (1,2)
SELECT @intNumTotalBD=COUNT(*) FROM @tblBD
WHILE @intContBD<=@intNumTotalBD
BEGIN
SELECT @intBDID=BDID,
@strBDName=BDName,
@intRecoveryModel=RecoveryModel
FROM @tblBD WHERE IDAux=@intContBD
SET @strSQL='ALTER DATABASE '+@strBDName+' SET RECOVERY SIMPLE'
exec sp_executesql @strSQL
--PRINT @strsQL
DECLARE @intLogTotal AS SMALLINT
DECLARE @intPos AS SMALLINT=1
DECLARE @strLogFile AS VARCHAR(4000)
INSERT INTO #tblLog (LogFilename)
SELECT name FROM sys.master_files
WHERE database_id=@intBDID AND type=1
SELECT @intLogTotal=COUNT(*)
FROM #tblLog
WHILE @intPos<=@intLogTotal
BEGIN
SELECT @strLogFile=LogFileName
FROM #tblLog WHERE IDRowLog=@intPos
SET @strSQL='USE '+@strBDName+' DBCC SHRINKFILE('+@strLogFile+')'
EXEC sp_executesql @strSQL
--PRINT @strSQL
SET @intPos+=1
END
TRUNCATE TABLE #tblLog
IF @intRecoveryModel=1
SET @strSQL='ALTER DATABASE '+@strBDName+' SET RECOVERY FULL'
ELSE
SET @strSQL='ALTER DATABASE '+@strBDName+ ' SET RECOVERY BULK_LOGGED'
exec sp_executesql @strSQL
--PRINT @strSQL
SET @intContBD+=1
END
DROP TABLE #tblLog
Aun así, también existen otras formas de lograr el mismo objetivo, con lo que podéis evaluar la opción que más os guste o entendáis mejor.
¡Enjoy T-SQL!
¡Enjoy T-SQL!
0 comentarios:
Publicar un comentario en la entrada