After you create a database,
you have the ongoing task of managing it. At the database level, this
task generally involves manipulating the file structure and setting
options appropriate for the usage of the database.
Managing File Growth
SQL Server manages file growth by
automatically growing files by preset intervals when a need for
additional space arises. However, this is a very loose definition of the
word manages.
What actually happens is that when the database runs out of space, it
suspends all update activity, checks whether it is allowed additional
space, and if space is available, it increases the file size by the
value defined by FILEGROWTH. When the database fills up again, the whole process starts over.
When
all the files in a filegroup are full and are configured to autogrow,
SQL Server automatically expands one file at a time in a round-robin
fashion to accommodate more data. For example, if a filegroup consists
of multiple files, and no free space is available in any file in the
filegroup, the first file is expanded by the specified file-growth
setting. When the first file is full again, and there is no more free
space elsewhere in the filegroup, the second file is expanded. When the
second file is full, and there is no more free space elsewhere in the
filegroup, the third file is expanded, and so on.
Because FILEGROWTH
can be defined as small as 64KB, automatically increasing the file size
can be detrimental to performance if it happens too frequently. When you
think of managing file growth, you can think of the database
administrator proactively monitoring the size of files and increasing
the size before SQL Server runs out of space when allocating new
extents. That’s not to say automatic file growth is a bad thing; it is,
in fact, a great “safety valve” to accommodate unpredictable data growth
or a lack of attention on the part of the administrator.
Expanding Databases
As previously discussed,
databases can be expanded automatically, or you can intervene and expand
them manually. The manual expansion can be accomplished by adding more
files to the database or by increasing the size of the existing files.
The database expansions can be accomplished with either SSMS or T-SQL.
To expand the size of the data
files using SSMS, you right-click the database in the Object Explorer
and select Properties. When the Database Properties dialog appears, you
select the Files page to list all the files associated with the
database. The Initial Size (MB) column displays the current disk
allocation for each file. You can enter the new size directly into the
column or use the up arrow to increase the size. After establishing the
new size, you can simply click OK to expand the database file, or you
can script the change by using the Script button at the top of the
Database Properties window.
You can also use the Files
page of the Database Properties dialog in SSMS to add files to a
database. You do this by clicking the Add button, which adds a new file
entry row into the Database Files grid. You must supply a logical name
for the new file, which typically contains the database name. In
addition, you must supply the other data values in the row, including
the file type, filegroup, initial size, autogrowth parameters, and path
to the file.
The T-SQL ALTER DATABASE command is another option you can use for expanding a database. Listing 1 shows an ALTER DATABASE example that increases the size of a data file in the AdventureWorks2008 database to 200MB.
Listing 1. Using T-SQL to Increase the Size of a Database File
ALTER DATABASE [AdventureWorks2008]
MODIFY FILE ( NAME = N'AdventureWorks2008_Data', SIZE = 200MB )
GO
|
You can also use the ALTER DATABASE command to add a new file to a database. Listing 2 shows an example that adds a new data file to the AdventureWorks2008 database.
Listing 2. Using T-SQL to Add a New Database File
ALTER DATABASE [AdventureWorks2008]
ADD FILE ( NAME = N'AdventureWorks2008_Data2',
FILENAME = N'C:\Program Files\Microsoft SQL
Server\MSSQL.1\MSSQL\DATA\AdventureWorks2008_Data2.ndf',
SIZE = 2048KB , FILEGROWTH = 1024KB ) TO FILEGROUP [PRIMARY]
GO
|
Shrinking Databases
Shrinking database files
is a bit more involved than expanding them. Generally, you do database
shrink operations manually, using DBCC commands. SQL Server does have
the AUTOSHRINK database option,
but it is usually reserved for development databases and should not be
used in production. The reason it is not recommended for production is
that the AUTOSHRINK operation can run at peak usage time and affect performance. AUTOSHRINK is executed when more than 25% of a file contains unused space. This event can occur, for example, after a large deletion.
If you want to shrink a database manually, you can do so by using DBCC SHRINKDATABASE, DBCC SHRINKDATAFILE, or SSMS. The following sections describe these three methods.
Note
Generally, you
should avoid shrinking database files if you believe that the files are
going to grow to the same larger size again. The continual expansion of a
database can affect performance while the expansion is occurring. Also,
if a database file is repeatedly shrunk and expanded, the database file
itself can become fragmented within the file system, which can degrade
I/O performance for the file.
Using DBCC SHRINKDATABASE to Shrink Databases
The DBCC SHRINKDATABASE
statement attempts to shrink all the files in a database and leave a
specified target percentage of free space. The following is an example
of the DBCC SHRINKDATABASE syntax and running the command against the AdventureWorks2008 database:
DBCC SHRINKDATABASE
( 'database_name' | database_id | 0
[ ,target_percent ]
[ , { NOTRUNCATE | TRUNCATEONLY } ]
)
[ WITH NO_INFOMSGS ]
--Shrink Example
DBCC SHRINKDATABASE (AdventureWorks2008, 25)
The first parameter of the DBCC SHRINKDATABASE command is the database_name or database_id,
and the second parameter is the desired percentage that will be left
free. In the preceding example, an attempt will be made to shrink the
database file and leave 25% free space in the files. This operation is
done one data file at a time, and the log files are treated as one unit
and shrunk together.
There are quite a few things to consider when you use the DBCC SHRINKDATABASE command. The following are some of the most important considerations:
DBCC SHRINKDATABASE
does not shrink a file smaller than its minimal size. The minimal size
is the size of the file when it was initially created or the size of the
file after it was explicitly resized. Explicit resizing can be
accomplished with the DBCC SHRINKFILE command.
The TRUNCATEONLY
option frees any unused space at the end of a file but does not attempt
any page movement within the file. The target percentage is ignored
when this option is specified.
The NOTRUNCATE
option attempts to move pages in the files to push all free space to
the end of the file. This option does not actually return the space to
the operating system, and the physical file does not end up smaller when
this option is used.
If neither the NOTRUNCATE nor TRUNCATEONLY options are specified, this is equivalent to running DBCC SHRINKDATABASE WITH NOTRUNCATE followed by DBCC SHRINKDATABASE WITH TRUNCATEONLY.
The first part attempts to push all the free space to the end of the
file; then the free space is released to the operating system, and the
file ends up smaller.
The database files can never be shrunk to a size smaller than the data contained within them.
For smaller databases, the DBCC SHRINKFILE
command is often considered to be a good choice because it is all
inclusive and applies to all the database files. For larger databases or
situations in which you need more control, you should consider using
the DBCC SHRINKFILE command, which is discussed in the next section.
Using DBCC SHRINKFILE to Shrink Databases
The DBCC SHRINKFILE
command operates on individual database files. For databases that
contain many database files, you must execute multiple commands to
shrink the entire database. This task requires some extra work, but the
increased control is often worth the effort. This, combined with the
fact that you can shrink a file below its minimum specified size, makes
it a very good option.
The following example shows the syntax for the DBCC SHRINKFILE command and a simple example for the AdventureWorks2008 database:
DBCC SHRINKFILE
(
{ ' file_name ' | file_id }
{ [ , EMPTYFILE]
| [ [ , target_size ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ]
}
)
[ WITH NO_INFOMSGS ]
-- sample shrink command
USE [AdventureWorks2008]
GO
DBCC SHRINKFILE (N'AdventureWorks2008_Data' , 180)
GO
DBCC SHRINKFILE (N'AdventureWorks2008_Log' , 10)
GO
Note that with this option, a filename or an ID is supplied, rather than the database name. DBCC SHRINKFILE must be run in the database that the file belongs to. You specify TARGET_SIZE in megabytes; this is the desired size for the file after the shrink completes. If TARGET_SIZE is not specified or the target size is too small, the command tries to shrink the file as much as possible. The EMPTYFILE
option migrates all data in the file to other files in the same
filegroup. No further data can be placed on the file. The file can
subsequently be dropped from the database. This capability can be useful
when you want to migrate a data file to a new disk. The NOTRUNCATE and TRUNCATEONLY options for DBCC SHRINKDATAFILE work the same way as with DBCC SHRINKDATABASE. Refer to the previous section for details.
Tip
If you would like to shrink every database file by using the DBCC SHRINKFILE command, you can generate the commands by using a SELECT statement. The following SELECT is an example of this:
SELECT 'PRINT ''LOGICAL NAME: ' + rtrim(name) +
' FILENAME: ' + rtrim(filename) + '''' + char(10) +
'go' + char(10) +
' DBCC SHRINKFILE (' + convert(varchar(8),fileid) + ',1)' +
char(10) + 'go' + char(10)
from sysfiles order by fileid
The results from this SELECT produce the DBCC SHRINKFILE
commands for all the files in the database that it is run against. You
can then paste the results into another query window and execute them.
This particular example uses a fixed target size of 1MB, but you can
adjust this size in the SELECT statement. You could also modify this SELECT statement so that it uses the sys.master_files catalog view instead of using sysfiles.
Shrinking the Log File
The
data file most likely to grow beyond a normal size and require periodic
shrinking is the transaction log file. If a user process issues a large
update transaction, the log file grows to the size needed to hold the
records generated by the transaction. This could be significantly larger
than the normal growth of the transaction log.
As with data files, shrinking
of the log file in SQL Server 2008 can take place only from the end of
the log file. However, you must first back up or truncate the log to
remove the inactive log records and reduce the size of the logical log.
You can then run the DBCC SHRINKFILE or DBCC SHRINKDATABASE command to release the unused space in the log file.
Transaction log files are
divided logically into segments, called virtual log files. The Database
Engine chooses the size of the virtual log files dynamically while it is
creating or extending log files. Transaction log files can only be
shrunk to a virtual log file boundary. It is therefore not possible to
shrink a log file to a size smaller than the size of a virtual log file,
even if the space is not being used. The size of the virtual log files
in a transaction log increase as the size of the log file increases. For
example, a database defined with a log file of 1GB may have virtual log
files 128MB in size. Therefore, the log can be shrunk to only about
128MB.
Because of the overhead
incurred when the autoshrink process attempts to shrink database files,
it is not recommended that you enable this option for the transaction
log because it could be triggered numerous times during the course of a
business day. It is better to schedule the shrinking of the log file to
be performed during normal daily maintenance, when production system
activity is at a minimum.
Using SSMS to Shrink Databases
In addition to shrinking a
database by using T-SQL, you can do so through SSMS. In the Object
Explorer, you right-click the database you want to shrink, and then you
choose Tasks, followed by Shrink. You can then select either Database or
Files. Selecting the Database option displays the Shrink Database
dialog (see Figure 1).
The currently allocated size and free space for the database are shown.
You have the option of selecting the Shrink Action and checking the
Reorganize Files Before Releasing Unused Space check box.
You can click the Script
button to generate the T-SQL that will be used to perform the database
shrink operation. When you do, a DBCC SHRINKDATABASE command is generated.
If you want to shrink database files, you choose the Files option instead of Database. Figure 2
shows the Shrink File dialog displayed when you select Files. You can
shrink one database file at a time using this window. If you choose the
shrink option Release Unused Space, SMSS uses the DBCC SHRINKFILE command with the TRUNCATEONLY option. If you choose the Reorganize Pages Before Releasing Unused Space option, SMSS uses the DBCC SHRINKFILE command without the TRUNCATEONLY or NOTRUNCATE option. As mentioned earlier, this causes page movement to free as much space as possible. A TRUNCATE operation then releases the free space back to the operating system.