Technical Article

Truncate Log File For All User Databases

,

The log file is too big? This is the solution

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO







ALTER        Procedure [dbo].[sp_EasyDetAtt] @MinSize int /* = 100 --(MB)*/,@RealDettach char(1)
AS
BEGIN
-- DataFiles List --
SET NOCOUNT ON
if exists (SELECT [id] 
	   FROM tempdb..sysobjects 
	   WHERE [id] = OBJECT_ID ('tempdb..#TempForFileStats '))
DROP TABLE #TempForFileStats 

DECLARE @DBName nvarchar(40)
DECLARE @SQLString nvarchar (2000)
DECLARE c_db CURSOR FOR
 		   SELECT name
    		   FROM master.dbo.sysdatabases
                   WHERE status&512 = 0 
                   AND dbid >4	

-- Create Temp Hold Result Tables --
CREATE TABLE #TempForFileStats([Server Name]          nvarchar(40),
                               [Database Name]        nvarchar(20),
                               [File Name]            nvarchar(128),
                               [Usage Type]           varchar (6),
                               [Size (MB)]            real, 
                               [Space Used (MB)]      real,
                               [MaxSize (MB)]         real,
                               [Next Allocation (MB)] real, 
                               [Growth Type]          varchar (12),
                               [File Id]              smallint,
                               [Group Id]             smallint,
                               [Physical File]        nvarchar (260),
                               [Date Checked]         datetime) 

CREATE TABLE #TempForDataFile ([File Id]             smallint,
                               [Group Id]            smallint,
                               [Total Extents]       int,
                               [Used Extents]        int,
                               [File Name]           nvarchar(128),
                               [Physical File]       nvarchar(260))

CREATE TABLE #TempForLogFile  ([File Id]             int, 
                               [Size (Bytes)]        real, 
                               [Start Offset]        varchar(30), 
                               [FSeqNo]              int, 
                               [Status]              int, 
                               [Parity]              smallint, 
                               [CreateTime]          varchar(20))   


DECLARE @tblConnectedUsers TABLE (SPID int)
DECLARE @KillExp VARCHAR(200),@iSPID   int
 



OPEN c_db
FETCH NEXT FROM c_db INTO @DBName
WHILE @@FETCH_STATUS = 0
   BEGIN
      SET @SQLString = 'SELECT @@SERVERNAME                     as  ''ServerName'', '          + 
                       '''' + @DBName + '''' + '                as  ''Database'', '            +  
                       '        f.name, '                                                      +
                       '       CASE '                                                          +
                       '          WHEN (64 & f.status) = 64 THEN ''Log'' '                     +
                       '          ELSE ''Data'' '                                              + 
                       '       END                              as ''Usage Type'', '           +
                       '        f.size*8/1024.00                as ''Size (MB)'', '            +
                       '        NULL                            as ''Space Used (MB)'', '      +
                       '        CASE f.maxsize '                                               +
                       '           WHEN -1 THEN  -1 '                                        +
                       '           WHEN  0 THEN  f.size*8/1024.00  '                           +
                       '           ELSE          f.maxsize*8/1024.00 '                         +
                       '        END                             as ''Max Size (MB)'', '        +
                       '        CASE '                                                         +
                       '           WHEN (1048576&f.status) = 1048576 THEN (growth/100.00)*(f.size*8/1024.00) ' + 

                       '           WHEN f.growth =0                 THEN 0 '                +
                       '           ELSE                                   f.growth*8/1024.00 ' +
                       '        END                             as ''Next Allocation (MB)'', ' +
                       '       CASE  '                                                         +
                       '          WHEN (1048576&f.status) = 1048576 THEN ''Percentage'' '      +
                       '          ELSE ''Pages'' '                                             +
                       '       END                              as ''Usage Type'', '           +
                       '       f.fileid, '                                                     +
                       '       f.groupid, '                                                    +
                       '       filename, '                                                     +
                       '       getdate() '                                                     +
                       ' FROM [' + @DBName + '].[dbo].[sysfiles] f' 
      INSERT #TempForFileStats 
      EXECUTE(@SQLString)
      ------------------------------------------------------------------------
      SET @SQLString = 'USE [' + @DBName + '] DBCC SHOWFILESTATS'
      INSERT #TempForDataFile
      EXECUTE(@SQLString)
      --
      UPDATE #TempForFileStats
      SET [Space Used (MB)] = s.[Used Extents]*64/1024.00
      FROM #TempForFileStats f,
           #TempForDataFile  s
      WHERE f.[File Id]       = s.[File Id]
        AND f.[Group Id]      = s.[Group Id]
        AND f.[Database Name] = @DBName
      --
      TRUNCATE TABLE #TempForDataFile
      -------------------------------------------------------------------------
      SET @SQLString = 'USE [' + @DBName + '] DBCC LOGINFO'
      INSERT #TempForLogFile
      EXECUTE(@SQLString)      
      --
      UPDATE #TempForFileStats 
      SET [Space Used (MB)] = (SELECT (MIN(l.[Start Offset]) + 
                                       SUM(CASE 
                                              WHEN l.Status <> 0 THEN  l.[Size (Bytes)] 
                                              ELSE           0 
                                           END))/1048576.00
                               FROM #TempForLogFile l
                               WHERE l.[File Id] = f.[File Id])
      FROM #TempForFileStats f
      WHERE f.[Database Name] = @DBName
      AND f.[Usage Type]    = 'Log'
      --
      TRUNCATE TABLE #TempForLogFile 
      -------------------------------------------------------------------------
      FETCH NEXT FROM c_db INTO @DBName
   END
CLOSE c_db
DEALLOCATE c_db
SET @DbName = ''

--- List Of Databases for detach/attaching

SELECT * FROM #TempForFileStats

SELECT  x.[Database Name]	as [Database Name],
	x.[Physical File] 	as ldf,
	y.[Physical File] 	as mdf,
	x.[File Name] 		as logname
FROM #TempForFileStats x
JOIN #TempForFileStats y
	ON (x.[Database Name] = y.[Database Name]
	AND y.[Usage Type] = 'Data'
	AND y.[File Id] = 1)
WHERE x.[Usage Type] = 'Log'
AND x.[File Id] = 2
AND x.[Size (MB)] >= @MinSize
---

DECLARE @DbPhysNameOld SYSNAME
DECLARE @DbPhysNameNew SYSNAME
DECLARE @DbMdfFileName SYSNAME
DECLARE @LogName       SYSNAME	
DECLARE @ShellCMD NVARCHAR(2000)
DECLARE @ShellForDelete NVARCHAR(2000)
DECLARE n_db CURSOR FOR SELECT x.[Database Name],x.[Physical File] as ldf,y.[Physical File] as mdf,x.[File Name] as logname
			FROM #TempForFileStats x
			JOIN #TempForFileStats y
				ON (x.[Database Name] = y.[Database Name]
				AND y.[Usage Type] = 'Data'
				AND y.[File Id] = 1)
			WHERE x.[Usage Type] = 'Log'
			AND x.[File Id] = 2
			AND x.[Size (MB)] >= @MinSize

OPEN n_db	
FETCH NEXT FROM n_db INTO @DbName,@DbPhysNameOld,@DbMdfFileName,@LogName
WHILE @@FETCH_STATUS = 0
	BEGIN
		print ltrim(rtrim(@DbName))+' '+ltrim(rtrim(@DbMdfFileName))
		INSERT INTO  @tblConnectedUsers
		SELECT p.spid
		FROM master.dbo.sysprocesses p WITH (NOLOCK)
		join master.dbo.sysdatabases d WITH (NOLOCK) 
			ON p.dbid = d.dbid
		WHERE d.[name] = @DbName
		IF @@ROWCOUNT > 0
		BEGIN
			WHILE 1 = 1
				BEGIN
					SELECT TOP 1 @iSPID = SPID
					FROM  @tblConnectedUsers
					WHERE SPID > ISNULL(@iSPID, 0) 
					ORDER BY SPID ASC 
					-- Break if no more users
					IF @@ROWCOUNT = 0
					BREAK
					SET @KillExp = 'Kill ' + CONVERT(VARCHAR(10), @iSPID)
					EXEC( @KillExp )	
				END	
		DELETE @tblConnectedUsers		
		END
		-- Detach database 
		if UPPER(@RealDettach)='Y'
			BEGIN
				EXEC master..sp_detach_db @Dbname,TRUE
				WAITFOR DELAY '00:00:05'
				EXEC xp_cmdshell 'cd c:\temp',NO_OUTPUT --check if c:\temp exists
				IF @@error = 1
					EXEC xp_cmdshell 'mkdir c:\temp',NO_OUTPUT --create c:\temp if not exists
              	-- Move (OS) The old log file to c:\temp
				IF CHARINDEX(' ',@DbPhysNameOld)>0
					SET @ShellCMD = 'MOVE "'+LTRIM(RTRIM(@DbPhysNameOld))+'" '+'c:\temp'
				ELSE
					SET @ShellCMD = 'MOVE '+LTRIM(RTRIM(@DbPhysNameOld))+' '+'c:\temp'
				PRINT LTRIM(RTRIM(@ShellCMD))
				EXEC master..xp_cmdshell @ShellCMD,NO_OUTPUT
				WAITFOR DELAY '00:00:05'
		-- Attach the single mdf file
		
			EXEC master..sp_attach_single_file_db @Dbname,@DbMdfFileName
			IF @@ERROR = 0
				BEGIN
					PRINT '****************************************************'
					PRINT @Dbname+' attaching success'
					PRINT '****************************************************'
							
				END
			ELSE 
				BEGIN
					PRINT '***************************************************'
					PRINT 'Check '+@Dbname+' and attach him manualy !!!'
					PRINT '***************************************************'
				END	
		END
		SET @ShellCMD = ''
		SET @DbPhysNameNew = ''
		FETCH NEXT FROM n_db INTO @DbName,@DbPhysNameOld,@DbMdfFileName,@LogName
	END
CLOSE n_db
DEALLOCATE n_db

DROP TABLE #TempForDataFile
DROP TABLE #TempForLogFile
DROP TABLE #TempForFileStats

END

GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

Rate

5 (1)

You rated this post out of 5. Change rating

Share

Share

Rate

5 (1)

You rated this post out of 5. Change rating