|
MohammedU
Posting Yak Master
145 Posts |
Posted - 2007-02-08 : 02:04:34
|
| SET QUOTED_IDENTIFIER ON GOSET ANSI_NULLS ON GOCREATE proc sp_force_shrink_log @target_percent tinyint = 0,@target_size_MB int = 10,@max_iterations int = 1000,@backup_log_opt nvarchar(1000) = 'with truncate_only'asset nocount on-- exec sp_force_shrink_log @target_percent = 0 , @target_size_MB = 1000declare @db sysname,@last_row int,@log_size decimal(25,2),@unused1 decimal(25,2),@unused decimal(25,2),@shrinkable decimal(25,2), @iteration int,@file_max int,@file int,@fileid varchar(5)select @db = db_name(),@iteration = 0create table #loginfo(id int identity,FileId int,FileSize numeric(25,0),StartOffset numeric(25,0),FSeqNo int,Status int,Parity smallint,CreateLSN Varchar(50))create table #logfiles ( id int identity(1,1), fileid varchar(5) not null )insert #logfiles ( fileid ) select convert( varchar, fileid ) from sysfileswhere status & 0x40 = 0x40select @file_max = @@rowcountif object_id( 'table_to_force_shrink_log' ) is nullexec( 'create table table_to_force_shrink_log ( x nchar(3000) not null )' )insert #loginfo ( FileId, FileSize, StartOffset, FSeqNo, Status, Parity,CreateLSN ) exec ( 'dbcc loginfo' )select @last_row = @@rowcountselect @log_size = sum( FileSize ) / 1048576.00,@unused = sum( case when Status = 0 then FileSize else 0 end ) /1048576.00,@shrinkable = sum( case when id < @last_row - 1 and Status = 0 thenFileSize else 0 end ) / 1048576.00from #loginfoselect @unused1 = @unused -- save for laterselect 'iteration' = @iteration,'log size, MB' = @log_size,'unused log, MB' = @unused,'shrinkable log, MB' = @shrinkable,'shrinkable %' = convert( decimal(6,2), @shrinkable * 100 /@log_size )while @shrinkable * 100 / @log_size > @target_percentand @shrinkable > @target_size_MBand @iteration < @max_iterations beginselect @iteration = @iteration + 1 -- this is just a precautionexec( 'insert table_to_force_shrink_log select name from sysobjectsdelete table_to_force_shrink_log')select @file = 0while @file < @file_max beginselect @file = @file + 1select @fileid = fileid from #logfiles where id = @fileexec( 'dbcc shrinkfile( ' + @fileid + ' )' )endexec( 'backup log ' + @db + ' ' + @backup_log_opt )truncate table #loginfoinsert #loginfo ( FileId, FileSize, StartOffset, FSeqNo, Status, Parity,CreateLSN ) exec ( 'dbcc loginfo' )select @last_row = @@rowcountselect @log_size = sum( FileSize ) / 1048576.00,@unused = sum( case when Status = 0 then FileSize else 0 end ) /1048576.00,@shrinkable = sum( case when id < @last_row - 1 and Status = 0 thenFileSize else 0 end ) / 1048576.00from #loginfoselect 'iteration' = @iteration,'log size, MB' = @log_size,'unused log, MB' = @unused,'shrinkable log, MB' = @shrinkable,'shrinkable %' = convert( decimal(6,2), @shrinkable * 100 /@log_size )endif @unused1 < @unusedselect 'After ' + convert( varchar, @iteration ) +' iterations the unused portion of the log has grown from ' +convert( varchar, @unused1 ) + ' MB to ' +convert( varchar, @unused ) + ' MB.'union allselect 'Since the remaining unused portion is larger than 10 MB,' where@unused> 10union allselect 'you may try running this procedure again with a higher number ofiterations.' where @unused > 10union allselect 'Sometimes the log would not shrink to a size smaller than severalMegabytes.' where @unused <= 10elseselect 'It took ' + convert( varchar, @iteration ) +' iterations to shrink the unused portion of the log from ' +convert( varchar, @unused1 ) + ' MB to ' +convert( varchar, @unused ) + ' MB'exec( 'drop table table_to_force_shrink_log' )GOSET QUOTED_IDENTIFIER OFF GOSET ANSI_NULLS ON GOMohammedU |
 |
|