Utilities Assess Data-File Usage and Provide Commands So You Can Do Something About It

Downloads
102295.zip

I created two T-SQL utilities

  • Candidate Commands (CandidateFileSizeMgmtCommands.sql); and
  • Candidate Commands Plus (CandidateFileSizeMgmtCommandsPlus.sql)

that you can use to manage the size of your data files. They provide not only information about disk and data-file usage but also commands you can use to shrink or grow the size of data files. The commands are based on a target (i.e., percentage of free space) that you specify, so they're tailored to your particular situation.

For example, suppose that your SQL Server machine has multiple databases. You receive a notice that the amount of free disk space on that machine is low. You also receive a notice that the amount of database free space is low for the database named DB. The limited amount of free disk space hampers your ability to quickly grow DB's data file.

In order to grow the data file for DB without depleting all available disk space, you must first free up some disk space by shrinking other data files. To identify which data files are good candidates to shrink, you can use the Candidate Commands utility. Figure 1 shows sample output from this tool.

Figure 1: Sample output from the Candidate Commands utility (click to enlarge)

Although all the columns provide useful information, the key columns are:

  • %DataFeeSpace. Specifies the current amount of free space in the data file as a percentage.
  • DiskFreeSpace. Indicates the amount of free space (in megabytes) on the physical drive.
  • SmallestForTarget. Specifies smallest file size necessary to meet your target percentage.
  • CandidateResult. Indicates how much the existing file would increase or decrease if you ran the command in the CandidateCommand column.
  • CandidateCommand. Provides the command to produce the desired result based on your target percentage.

Which databases are good candidates for shrinking and growing depends on your goal. For example, suppose you ran the Candidate Commands utility and received the results shown in Figure 1. Which commands you'd want to run depends on what you're trying to accomplish:

  • If you're making sure your data files have enough free space, the results show that the free space for the Products database's data files is quite low. There's plenty of disk space on the H and I drives, so you'd want to execute the commands for the Products database to increase the amount of space allocated to its data files.
  • If you know there will be a large insertion of data in the Sales database and you want to ensure there's adequate space, the results show that there's plenty of available space for its data files. So, in this case, the best course of action is to not run any of the commands.
  • If you need to add a really large database to the server and you want to shrink data files to free up disk space, the results show that shrinking the Sales data files will result in the biggest amount of freed up disk space.

Here's how to run the Candidate Commands utility:

  1. Log in to the SQL Server machine on which you want to check data-file usage.
  2. Open SQL Server Management Studio (SSMS) and paste the contents of CandidateFileSizeMgmtCommands.sql into a new query window.
  3. Modify the target free-space percentage if desired. The default value is 20 percent. If you want a different percentage, find the line
    SET @target = 20
    and replace 20 with the desired target.
  4. Execute CandidateFileSizeMgmtCommands.sql.

The Candidate Commands utility doesn't make any data modifications. It merely proposes commands based on the specified free-space percentage target. After you pick a command to execute, you can copy and paste that command into a new query window and execute it. The script will produce a warning if there's insufficient disk space to increase the size of a data file for a given target.

The Candidate Commands Plus utility is similar to the Candidate Commands utility, but differs in two important respects. First, Candidate Commands Plus is designed to be executed against a list of servers. Second, the produced commands have the proper syntax to be executed in one query window against multiple remote servers. Because of these differences, it uses an additional file named CC.sql.

Here's how to run the Candidate Commands Plus utility:

  1. Log in to one of your SQL Server machines.
  2. Save CC.sql to a location that the SQL Server service can access (e.g., C:\dpg).
  3. Open SSMS and paste the contents of CandidateFileSizeMgmtCommandsPlus.sql into a new query window.
  4. Modify the target free-space percentage if desired. The default value is 30 percent. If you want a different percentage, find the line
    SET @target = 30
    and replace 30 with the desired target.
  5. Modify the location of the CC.sql file. Find the line
    SET @file = N'c:\dpg\CC.sql'
    replace c:\dpg\CC.sql with the location in which you placed CC.sql. It must be a fully qualified pathname. (Leave in the letter N and the single quotes.)
  6. Modify the list of servers to be inserted into the @Servers variable. Find the code
    INSERT @Servers
    SELECT N'Server1' UNION ALL
    SELECT N'Server2' UNION ALL
    SELECT N'Server3' UNION ALL
    SELECT N'Server4' UNION ALL
    SELECT N'Server5'
    Replace Server1, Server 2, and so on with the names of your servers. (Leave in the letter N and the single quotes.) You can increase or decrease the number of servers as desired. (No matter the number, the last SELECT statement should not include the UNION ALL clause.)
  7. Execute CandidateFileSizeMgmtCommandsPlus.sql.

The output generated by the Candidate Commands Plus utility is similar to the output generated by the Candidate Commands utility. However, the candidate commands generated by Candidate Commands Plus are designed to be executed in SQLCMD mode, so they all start with :connect followed by the appropriate server name, as Figure 2 shows.

Figure 2: Sample candidate commands from the Candidate Commands Plus utility (click to enlarge)

After you decide on which commands to use, copy and paste the desired commands into a new query window, adding carriage returns where appropriate (see Figure 3).

Figure 3: Running commands in a query window in SQLCMD mode (click to enlarge)


Execute the commands in SQLCMD mode. By running the commands this way, you can execute multiple commands against multiple servers without needing to constantly change server connections.

The Candidate Commands and Candidate Commands Plus utilities let you quickly assess your available disk space and available data-file space. These scripts decrease human error by calculating the appropriate new data-file size value based on the target you provide. Further, with Candidate Commands Plus, you can quickly review disk and data-file usage on hundreds of SQL Server machines and execute as many commands as you desire against multiple servers in one query window. You can download CandidateFileSizeMgmtCommands.sql, CandidateFileSizeMgmtCommandsPlus.sql, and CC.sql by clicking the 102295.zip hotlink near the top of the page. The scripts have been tested on SQL Server 2008 and SQL Server 2005 machines.

Discuss this Article 7

gbegin
on Aug 8, 2009
This sounded like a great script, however there seems to be a problem with it. When you try to run the 'CandidateFileSizeMgmtCommands.sql' against a SQL 2000 or SQL 2005 database you get the error 'EXECUTE cannot be used as a source when inserting into a table variable.' at this line of code 'INSERT INTO @DiskInfo EXEC master..xp_fixeddrives'. Not sure how anyone has actually been able to run the script as posted.
Brent (not verified)
on Aug 19, 2009
This is really, really, REALLY dangerous advice that can cause performance problems. I responded to it in full here: http://www.brentozar.com/archive/2009/08/stop-shrinking-your-database-files-seriously-now/
Brent (not verified)
on Aug 20, 2009
David - thanks for responding. When you say "The article is narrow in scope and gives NO ADVICE," it seems to ignore one of the early lines in the article: "In order to grow the data file for DB without depleting all available disk space, you must first free up some disk space by shrinking other data files." You're telling the DBA that their only option - not one of, but their ONLY option - is to shrink other data files. That's bad advice, and that's what we're trying to avoid. One other option might be to find out why the other data files are large, and get the right amount of disk space to handle the problem. Otherwise, with your solution, you're recommending that they keep growing and shrinking different files, which ends up being a fragmentation nightmare. If you could have included the other options in the article, just like you explained them in the comments, then the article would have stood great on its own. Otherwise, it comes off as an instruction manual on how to build a handgun. While some publications have no problem explaining how to build a handgun, my hope is that we strive for a higher level of education at SQL Server Magazine. If we start publishing articles on how to truncate tables or how to format drives - without explaining the risks and drawbacks - then we're doing a bad job of educating the community.
KBemowski
on Aug 20, 2009
We asked the David to respond to these comments. He noted that, "The script is a tool. The script does not make any changes. The article is narrow in scope and gives NO ADVICE. The article is not in regards to file management and does not attempt to be all encompassing. There are countless articles regarding file management, I don’t desire to write another one. No DBA should attempt to read one single article on one single issue and expect his/her training to be complete. Learn file management elsewhere. As Paul Randal states in his post 'Why you should not shrink your data files': 'Bottom line - TRY TO AVOID running data file shrink at all costs!' (I added the emphasis on 'try to avoid'.) If the competent DBA decides a file needs to be shrunk OR GROWN, this script can assist the DBA." "I created this script because of one particular server that had 24 databases and no free disk space. One of the databases ran out of database free space. I could not unilaterally truncate tables, or move databases to a different server or add physical drives. The only thing I could do instantly was rob Peter to pay Paul. Yes. I shrunk the file of Database A so I could increase the file for Database B. That gave me time to THEN come up with a long term solution." Karen Bemowski, senior editor, SQL Server Magazine, Windows IT Pro
KBemowski
on Aug 22, 2009
Of all the things to get excited about in the MSSQL world, I never thought shrinking databases would be one of them. To me, it has always been a no-brainer. I'm running out of disk space, and I find a database with a ton of free space. What do I do? I shrink it! Somebody issues a massive update statement that grows the transaction log beyond all reason. What do I do? I shrink it! I'm a shrinker, and I'm not ashamed of it! Now before you go an accuse me of being a "no-brainer" myself, hear me out. I'm a DBA consultant. I have multiple large clients who have hundreds upon hundreds of databases. Most of these databases haven't been given the love and attention they deserve. As a result, I often inherit poorly managed systems and end up spending most of my time putting out fires. The single most occurring fire is low disk space. Not every organization is blessed with endless terabytes of disk storage. One of my clients has a large virtual server farm, and each virtual server gets just about enough disk space to hold the main database and a few backup files. Yes, I know, I have more space on my MP3 player, but this is the "do more with less" world I work in. Unless the DBA team cries for more space, we're stuck with what we're given. New servers crop up faster than we can document, let alone manage. Since adding more disk space requires a reboot, we usually have to shrink the data files and transaction log in order to keep the server up and running. That being said, a DBA should still exercise caution prior to shrinking/truncating a live production database. Outages need to be scheduled, backups need to be confirmed, etc. As the author stated in his response, sometimes you have to do what you have to do. And his script helps me do just that. What it comes down to is that if you shrink a database, you really need to defragment the indexes and data pages. But you are already doing that regularly anyway, right? Posted on behalf of Bill McEvoy
jsegarra
on Aug 19, 2009
I'm sorry but you really shouldn't be shrinking databases in the first place. No offense... http://www.brentozar.com/archive/2009/08/stop-shrinking-your-database-files-seriously-now/
gbegin
on Aug 8, 2009
.... disregard previous comment - works fine in SQL 2005. Need some modifications to work on sql 2000.

Please or Register to post comments.

IT/Dev Connections

Las Vegas
September 30th - October 4th

Paul ThurottOur Experts will show you:
• Common SQL Server
Problems
• Best Practices for T-SQL
• SQL Server Integration
Services
• Database Development

Come See Michael Otey & Tim Ford in Person!

Early Registration Now Open

From the Blogs
May 21, 2013
blog

A Common Misconception about MAXDOP

Out of the box, SQL Server is (and has been) able to take advantage of multiple processors/cores without any effort on behalf of administrators....More
May 9, 2013
blog

My ISO 8601-Compliant Signature 2

My family recently just "officially" announced that we're in the process of adopting a child from South Africa. We're quite excited, of course, but there's a ton of paperwork to do—along with the need for gobs of signatures....More
May 8, 2013
blog

Use SSIS for ETL from Hadoop

In this blog post, Mark Kromer walks you through using SSIS as a way to use ETL techniques using Microsoft's Hadoop on Windows (HDInsight) as a source using Hive connectors...More
SQL Server Pro Forums

Get answers to questions, share tips, and engage with the SQL Server community in our Forums.