|
|
|
Grasshopper
      
Group: General Forum Members
Last Login: Tuesday, February 28, 2012 6:16 AM
Points: 12,
Visits: 118
|
|
Hi, I'm trying to figure out why DBCC SHRINKFILE doesn't adhere to the specified file size of my database. I want my data file to have a fixed size of 4096 megabytes, no more, no less. So I use ALTER DATABASE to specify the new size. But when I tried to shrink my database, it shrunk below the minimum size. Bummer! I started investigating how the shrink command works.
Here is what Microsoft says about DBCC SHRINKFILE: (http://technet.microsoft.com/en-us/library/ms189493%28SQL.90%29.aspx)
DBCC SHRINKFILE, target_size: Is the size for the file in megabytes, expressed as an integer. If not specified, DBCC SHRINKFILE reduces the size to the default file size. The default size is the size specified when the file was created, or the last size set by using ALTER DATABASE.
However, my experience is that the shrink command doesn't behave this way. I have put together the following T-SQL code to illustrate this:
/* Create database, with default size of 4096 megabytes. */ CREATE DATABASE Testdb ON PRIMARY (NAME = N'Testdb_data', FILENAME = N'C:\Program files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\Testdb_data.mdf' , SIZE = 4096MB, FILEGROWTH = 0) LOG ON (NAME = N'Testdb_log', FILENAME = N'C:\Program files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\Testdb_log.ldf' , SIZE = 1024KB, FILEGROWTH = 10%) GO
/* Use the new database */ USE Testdb GO
/* Shrink the data file, no size specified = use default file size. Size won't go below 4096 megabytes, Windows Explorer confirms this. Repeatedly executing this command doesn't change the data file size. This is expected behavior. */ DBCC SHRINKFILE (N'Testdb_data') GO
/* Shrink the data file to 1024 megabytes. Size does indeed change to 1024 megabytes, Windows Explorer confirms this. This is expected behavior. */ DBCC SHRINKFILE (N'Testdb_data', 1024) GO
/* Alter database, change default data file size to 4096 megabytes again. Data file grows from 1024 to 4096 megabytes, Windows Explorer confirms this. This is expected behavior. */ ALTER DATABASE Testdb MODIFY FILE (NAME = N'Testdb_data', SIZE = 4096MB, FILEGROWTH = 0) GO
/* Shrink the data file, no size specified = use default file size. (ie. 4096 megabytes) Data file shrinks to 1024 megabytes again, Windows Explorer confirms this. Why??? This is confusing to me. I explicitly set the default size to 4096 megabytes using ALTER DATABASE below. Expected behavior: data file should not shrink below default size of 4096 megabytes. */ DBCC SHRINKFILE (N'Testdb_data') GO
Can someone please explain this behavior to me? Thank you!
|
|
|
|
|
SSC-Insane
         
Group: General Forum Members
Last Login: Today @ 4:34 PM
Points: 21,615,
Visits: 27,445
|
|
|
|
|
|
SSChampion
        
Group: General Forum Members
Last Login: Friday, May 17, 2013 12:22 PM
Points: 10,571,
Visits: 11,871
|
|
|
|
|
|
Mr or Mrs. 500
      
Group: General Forum Members
Last Login: 2 days ago @ 1:04 PM
Points: 574,
Visits: 684
|
|
| If you want the database to stay at exactly 4gb, then just set its initial size to that and disable autogrowth. There is no need to shrink it after that (which is also very bad for the database, as mentioned).
|
|
|
|
|
SSC Eights!
      
Group: General Forum Members
Last Login: Thursday, April 18, 2013 5:52 AM
Points: 908,
Visits: 2,797
|
|
| Of course, setting a fixed size with no autogrowth has its own inherent risks.
|
|
|
|
|
SSCarpal Tunnel
       
Group: General Forum Members
Last Login: Friday, May 17, 2013 11:21 AM
Points: 4,317,
Visits: 9,216
|
|
As everyone else has already stated - you shouldn't be shrinking the data file.
With that said, to answer your question - DBCC SHRINKFILE is working as expected. When you grow a data file, the initial size does not change. The initial size of the file is defined when you initially create the data file, or when you explicitly shrink the data file using the target size.
In your outline, when you performed the shrink to 1024 - then grew the file back to 4096 the initial size of the file is still 1024. When you performed the last shrink without a target size it was able to shrink to the initial size of the file.
Jeffrey Williams Problems are opportunites brilliantly disguised as insurmountable obstacles.
How to post questions to get better answers faster Managing Transaction Logs
|
|
|
|
|
Grasshopper
      
Group: General Forum Members
Last Login: Tuesday, February 28, 2012 6:16 AM
Points: 12,
Visits: 118
|
|
Thanks, I know I shouldn't be shrinking my database. I'm just trying to figure out how shrinking works and how it relates to the initial/default file size.
I argue that DBCC SHRINKFILE is not working as expected. Let me quote Microsoft again:
DBCC SHRINKFILE, target_size: Is the size for the file in megabytes, expressed as an integer. If not specified, DBCC SHRINKFILE reduces the size to the default file size. The default size is the size specified when the file was created, or the last size set by using ALTER DATABASE. http://technet.microsoft.com/en-us/library/ms189493%28SQL.90%29.aspx
First I execute ALTER DATABASE to change the default size to 4096 megabytes. Then I execute DBCC SHRINKFILE without specifying target_size. DBCC SHRINKFILE ignores the "last size set by using ALTER DATABASE" and shrinks to 1024 megabytes. For me this raises a couple of questions: -How do you change the "initial size" of a database after you created it? -When you execute ALTER DATABASE and specifies a new SIZE, does that change the "initial size"? -Documentation refers to "default size", is that the same as the "initial size"?
Thanks.
|
|
|
|
|
Grasshopper
      
Group: General Forum Members
Last Login: Tuesday, February 28, 2012 6:16 AM
Points: 12,
Visits: 118
|
|
I must have encountered a bug in SQL Server 2005: When you increase the initial size of a database using ALTER DATABASE, the DBCC shrinking commands ignores that size. The following code illustrates this:
/* Create Testdb1 with initial size = 4096MB */ CREATE DATABASE Testdb1 ON PRIMARY (NAME = N'Testdb1_data', FILENAME = N'C:\Program files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Testdb1_data.mdf', SIZE = 4096MB, FILEGROWTH=1024KB) LOG ON (NAME = N'Testdb1_log', FILENAME = N'C:\Program files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Testdb1_log.ldf', SIZE = 1024KB , FILEGROWTH=10%) GO
/* Create Testdb2 with initial size = 3MB */ CREATE DATABASE Testdb2 ON PRIMARY (NAME = N'Testdb2_data', FILENAME = N'C:\Program files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Testdb2_data.mdf', SIZE = 3MB, FILEGROWTH=1024KB) LOG ON (NAME = N'Testdb2_log', FILENAME = N'C:\Program files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Testdb2_log.ldf', SIZE = 1024KB , FILEGROWTH=10%) GO
/* Increase initial size of Testdb2 to 4096MB */ ALTER DATABASE Testdb2 MODIFY FILE (NAME = N'Testdb2_data', SIZE = 4096MB) GO
/* Shrink both databases. Here is the result: Testdb1_data.mdf = 4096MB Testdb2_data.mdf = 3MB (expected result: 4096MB) */ DBCC SHRINKDATABASE('Testdb1') DBCC SHRINKDATABASE('Testdb2') GO
|
|
|
|
|
SSCarpal Tunnel
       
Group: General Forum Members
Last Login: Friday, May 17, 2013 11:21 AM
Points: 4,317,
Visits: 9,216
|
|
If you truly think this is a bug (it isn't), then put in your issue at Connect and let Microsoft know.
Now, the reason this is not a bug is because initial_size <> default_size - and the only way the initial size is defined is either:
1) When the database is created... 2) When the size is changed using DBCC SHRINKFILE with the target_size parameter.
Jeffrey Williams Problems are opportunites brilliantly disguised as insurmountable obstacles.
How to post questions to get better answers faster Managing Transaction Logs
|
|
|
|
|
Grasshopper
      
Group: General Forum Members
Last Login: Tuesday, February 28, 2012 6:16 AM
Points: 12,
Visits: 118
|
|
Hi, thanks for your input. If this is the expected behavior of the shrink command, then the documentation is wrong or misleading: http://msdn.microsoft.com/en-us/library/ms190488(v=SQL.90).aspx
The database cannot be made smaller than the minimum size of the database. The minimum size is the size specified when the database is originally created, or the last size explicitly set by using a file size changing operation such as DBCC SHIRNKFILE or ALTER DATABASE. So the question is whether there's something wrong the documentation or the command itself?
|
|
|
|