zoukankan      html  css  js  c++  java
  • Shrink DB and Log

    Original link: http://www.sqlservercentral.com/scripts/63782/

    This has been tested on SQL 2000, 7 and 2005 databases very successfully. 40 GB went down to under 1 GB, 176GB went down to 105MB

    /*
    Shrink a named transaction log file belonging to a database

    Originally found at;

    http://support.microsoft.com/support/kb/articles/q256/6/50.asp

    Changes:
    28.04.2004
    Modified the inner loop so it tested the dx time so long overruns did not happen
    Modified the inner loop so it had a fixed minimum quantity so there was no skip in skip out

    29.03.2006
    Modified the inner loop so it had a dynamic minimum quantity to allow faster shrinkage

    24.05.2006
    Modified the USE statement so it uses brackets around the dbname
    Modified the @TruncLog variable so it uses brackets around the dbname

    31.06.2006
    Modified the code to use PRINT instead of SELECT in several cases
    Modified the code to use @MaxCount instead of two unclear rules
    Modified the code to use @Factor instead of several hard-coded values
    Commented the use of @Factor
    Moved the configuration and @Counter init code to before the start of the first loop to avoid repetition
    Modified the code to display the process runtime in seconds rather than minutes

    */

    SET NOCOUNT ON

    DECLARE @LogicalFileName SYSNAME,
            @MaxMinutes INT,
            @NewSize INT,
            @Factor FLOAT

    /*
      The process has several control parameters, most of the time you only need to worry about the first four
        as these are the big controls whereas the fifth is simply a fine tuning control which rarely needs to
        come into play.
    */

    --This is the name of the database for which the log will be shrunk.
    USE [databasename]

    --Use sp_helpfile to identify the logical file name that you want to shrink.
    SET @LogicalFileName = 'database_Log';
    --Limit on time allowed to wrap log in minutes
    SET @MaxMinutes = 5;
    --Ideal size of logfile in MB
    SET @NewSize =100;

    /*
      Factor determining maximum number of pages to pad out based on the original number of pages in use
        (single page = 8K).  Values in the range 1.0 - 0.8 seems to work well for many databases.

      Increasing the number will increase the maximum number of pages allowed to be padded, which should
        force larger amounts of data to be dropped before the process finishes.  Often speeds up shrinking
        very large databases which are going through the process before the timer runs out.

      Decreasing the number will decrease the maximum number of pages allowed to be padded, which should
        force less work to be done.  Often aids with forcing smaller databases to shrink to minimum size
        when larger values were actually expanding them.

    */
    SET @Factor = 1.0;                       

    /*
      All code after this point is driven by these parameters and will not require editing unless you need to
        fix a bug in the padding/shrinking process itself.
    */

    -- Setup / initialize
    DECLARE @OriginalSize INT,
            @StringData VARCHAR(500)

    SELECT @OriginalSize = size -- in 8K pages
    FROM sysfiles
    WHERE name = @LogicalFileName;

    SELECT @StringData = 'Original Size of ' + db_name() + ' LOG is ' +
        CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' +
        CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB'
    FROM sysfiles
    WHERE name = @LogicalFileName;

    PRINT @StringData;
    PRINT ''

    --Drop the temporary table if it already exists
    IF ( OBJECT_ID('[dbo].[DummyTrans]') IS NOT NULL )
      DROP TABLE [DummyTrans]

    CREATE TABLE [DummyTrans]( [DummyColumn] CHAR(8000) NOT NULL );

    -- Wrap log and truncate it.
    DECLARE @Counter   INT,
            @MaxCount  INT,
            @StartTime DATETIME,
            @TruncLog  VARCHAR(500)

    -- Try an initial shrink.
    DBCC SHRINKFILE (@LogicalFileName, @NewSize)

    SET @TruncLog = 'BACKUP LOG [' + db_name() + '] WITH TRUNCATE_ONLY';
    EXEC (@TruncLog)

    -- Configure limiter
    IF @OriginalSize / @Factor > 50000
        SET @MaxCount = 50000
    ELSE
        SET @MaxCount = @OriginalSize * @Factor

    -- Attempt to shrink down the log file
    PRINT 'Minimum Quantity : '+CAST( @MaxCount AS VARCHAR(10) )
    PRINT 'Maximum Time : '+CAST( @MaxMinutes AS VARCHAR(10) )+' minutes ('+CAST( @MaxMinutes*60 AS VARCHAR(10) )+' seconds)'
    PRINT ''

    SET @Counter = 0;
    SET @StartTime = GETDATE();

    --loop the padding code to reduce the log while
    -- within time limit and
    -- log has not been shrunk enough
    WHILE (
        (@MaxMinutes*60 > DATEDIFF(ss, @StartTime, GETDATE())) AND
        (@OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName)) AND
        ((@OriginalSize * 8 / 1024) > @NewSize)
    )
    BEGIN --Outer loop.

        --pad out the logfile a page at a time while
        -- number of pages padded does not exceed our maximum page padding limit
        -- within time limit and
        -- log has not been shrunk enough
        WHILE (
            (@Counter < @MaxCount) AND
            (@MaxMinutes*60 > DATEDIFF(ss, @StartTime, GETDATE())) AND
            (@OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName)) AND
            ((@OriginalSize * 8 / 1024) > @NewSize)
        )
        BEGIN --Inner loop
           
            INSERT INTO DummyTrans VALUES ('Fill Log')  -- Because it is a char field it inserts 8000 bytes.
            DELETE FROM DummyTrans
            SELECT @Counter = @Counter + 1

            --Every 1,000 cycles tell the user what is going on
            IF ROUND( @Counter , -3 ) = @Counter
            BEGIN
                PRINT 'Padded '+LTRIM( CAST( @Counter*8 AS VARCHAR(10) ) )+'K @ '+LTRIM( CAST( DATEDIFF( ss, @StartTime, GETDATE() ) AS VARCHAR(10) ) )+' seconds';
            END
        END

        --See if a trunc of the log shrinks it.
        EXEC( @TruncLog )

    END
    PRINT ''

    SELECT @StringData = 'Final Size of ' + db_name() + ' LOG is ' +
       CONVERT(VARCHAR(30),size) + ' 8K pages or ' +
       CONVERT(VARCHAR(30),(size*8/1024)) + 'MB'
    FROM sysfiles
    WHERE name = @LogicalFileName;

    PRINT @StringData
    PRINT ''

    DROP TABLE DummyTrans;
    PRINT '*** Perform a full database backup ***'

    SET NOCOUNT OFF

  • 相关阅读:
    jquery 停止animate动画,并且回复最初状态
    php mysql实体字符
    ECSHOP MYSQL 公用类库中的autoExecute方法
    ecshop 订单编号 get_order_sn
    ecshop 调用收货地址
    init.php 建立自己的前端共享文件
    php 生成随机字符串 abcdeft....789
    ecshop 订单-》订单状态 2
    ecshop后台,listtable.js使用
    ecshop Admin后台商品列表处(上架、下架、精品...取消精品)增加操作
  • 原文地址:https://www.cnblogs.com/liunatural/p/1511904.html
Copyright © 2011-2022 走看看