Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « Report Manager / Report Server Loading Slow InitiallyDelete all data in database (when you have FKs) »
    comments

    My favorite topic, "The SHRINK!"

    The topic really does cause pain. Shrinking a file in SQL Server is inherently a terrible action to take. However, we all know that in some cases when maintenance was never setup and recovery models were not properly chosen, the need does come up. An interesting topic came up on LTD in the forums regarding moving an overloaded and unmaintained log file to a server that had less disk space than the original. The first inclination would be to shrink the log and then backup/restore it to the new location. Seeing as the full backup consists of the data and just enough log to recover, the assumption would be that you would only get this in the new database. However, in this case, shrinking the log will not be the last step in the process. The initial size of the log will also need to change.

    Let’s take a look…

    In this case let’s say we have a database that is 300MB with a transaction log that is 3000MB.

    The database is a test log shipping database we will pick on named, “LOGSHIP_PUB”

    We can see by Size that we have the 300MB mdf and 3000MB log file.

    Now assuming we ran a shrinkfile on the log file, we could use DBCC SQLPERF(logspace) to check the logs free space.

    1. create table #temp (DatabaseName sysname, LogSize float, SpaceUsedPerc float, Status bit)
    2. insert #temp EXEC ('dbcc sqlperf(logspace)')
    3. select SpaceUsedPerc from #temp where DatabaseName = 'LOGSHIP_PUB'

    Resulting in 0.028… give or take a few thousands places.

    The initial thought may be to run a backup now and move the database over. You should see if you run a full backup on the database, the size will only be around 2MB.

    The problem we will run into will be when this backup is restored. Even knowing the backup shows the 2MB, this is only the data and log to the point of recovering retained in the backup. You may find yourself copying this backup considering the restore to be limited to what is in it. What will happen is the restore will take the Meta for the database and create the initial sizes for the files contained in it. This will result in a required space of all the files initial sizes. In our case that totals 3300MB + the padding required.

    Best way to see is by example so let’s restore the database.

    1. RESTORE DATABASE [LOGSHIP_PUB_SECONDARY] FROM  DISK = N'C:\LOGSHIP_PUB_FULL.bak'
    2.     WITH  FILE = 1,  
    3.     MOVE N'LOGSHIP_PUB' TO N'C:\LOGSHIP_PUB_SECONDARY.mdf',  
    4.     MOVE N'LOGSHIP_PUB_log' TO N'C:\LOGSHIP_PUB_SECONDARY_1.ldf',  
    5.     NOUNLOAD,  REPLACE,  STATS = 10
    6. GO

    First thing we may notice is the time this restore takes. It will be slightly more than expected from a 300MB database. Your typical IO should give this in around a 2-3 seconds but given the need to expand the log(s) and any other files that may consist in the restore, the time will be lengthened slightly. Of course this varies given different resources and even more when compression is involved.
    Our successful restore…

    SQL Server parse and compile time:
    CPU time = 0 ms, elapsed time = 1 ms.
    63 percent processed.
    100 percent processed.
    Processed 200 pages for database 'LOGSHIP_PUB_SECONDARY', file 'LOGSHIP_PUB' on file 1.
    Processed 1 pages for database 'LOGSHIP_PUB_SECONDARY', file 'LOGSHIP_PUB_log' on file 1.
    RESTORE DATABASE successfully processed 201 pages in 93.555 seconds (0.016 MB/sec).

    Checking our size and space utilized we should see the same results from the initial database

    1. Select [size],[name],[filename] from sysaltfiles

    So the bottom-line…

    Moving databases using backup/restore is a good method if your activity allows for this method. Just ensure a few things

    • If log maintenance was not performed and you are stuck in Full recovery while finding the need for a shrink, you can do this successfully without a truncate_only but don’t forget to resize your files.
    • Do the full backup after the resize to prevent longer restores and maintaining the disk usage you really require.
    • A well maintained transaction log structure will prevent all of this. You will know precisely the sizing requirements at this level.



    About the Author

    Ted Krueger is a SQL Server MVP and has been working in development and database administration for 13+ years. Specialties range from High Availability and Disaster / Recovery setup and testing methods down to custom assembly development for SQL Server Reporting Services. Ted blogs and is also one of the founders of LessThanDot.com technology community. Some of the articles focused on are Backup / Recovery, Security, SSIS and working on SQL Server and using all of the SQL Server features available to create stable and scalable database services. @onpnt
    Social SitingsTwitterLinkedInLTD RSS Feed
    1903 views
    Instapaper

    4 comments

    Comment from: SQLDenis [Member] Email
    SQLDenis RESTORE DATABASE successfully processed 201 pages in 93.555 seconds (0.016 MB/sec)



    What? are you running on a Zip disk? Or is your chip a Dorito?

    Here is what I get

    RESTORE DATABASE successfully processed 5542177 pages in 456.590 seconds (94.829 MB/sec)


    05/27/10 @ 07:03
    Comment from: Ted Krueger (onpnt) [Member]
    Ted Krueger (onpnt) >>What? are you running on a Zip disk? Or is your chip a Dorito?

    Man, I can't stop laughing!! LMAO And that's a "Cool Ranch" Dorito!
    05/27/10 @ 07:09
    Comment from: Erik [Member] Email
    Erik On the general subject of shrinking databases to recover space, remember that this can totally fragment all your tables and indexes. The best way to reclaim space without fragmentation is to rebuild all the clustered indexes on a new filegroup, WITH MOVE (I forget the exact syntax now). When the old filegroup is empty it can be dropped. Voila, your database is shrunk and NOT fragmented.
    05/27/10 @ 10:16
    Comment from: SQLDenis [Member] Email
    SQLDenis Emtucifor,

    That is correct, here is the syntax

    DROP INDEX IX_Bla
    ON SOmeTAble
    WITH (ONLINE = ON, MOVE TO NewFileGroup);
    05/27/10 @ 10:38

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)