3. Managing the Transaction Log
Each database in SQL Server has at least one
transaction log file. The transaction log file contains the transaction
log records for all changes made in that database. By default,
transaction log files have the file extension .ldf.
A database can have several log files, and
each log file can have a maximum size of 32TB. A log file cannot be part
of a filegroup. No information other than transaction log records can
be written to a log file.
Regardless of how many physical files have been
defined for the transaction log, SQL Server treats it as one contiguous
file. The transaction log for a database is actually managed as a set of
virtual log files (VLFs). VLFs have no fixed size, and there is no
fixed number of VLFs for a physical log file. The size and number of
VLFs is not configurable. SQL Server determines the size of the VLFs
dynamically, based on the total size of all the log files and the growth
increment specified for the log. Figure 5 shows an example of a physical log file divided into multiple virtual log files.

The transaction log is essentially a wrap-around
file. Initially, the logical log file begins at the start of the
physical log file. As transactions are committed, new log records are
added to the end of the logical log, and the logical log expands toward
the end of the physical log. When the logical log reaches the end of the
physical log file, SQL Server attempts to wrap around and start writing
log records back at the beginning of the physical log file, as shown in
Figure 6.

SQL Server, however, can reuse only the first VLF if
it is no longer part of the logical log; that is, the VLF does not
contain any active log records, and the contents of the inactive VLFs
have been truncated. Log truncation frees any virtual logs whose records
all appear before the MinLSN. The MinLSN is the log sequence number of
the oldest log record required for a successful database recovery.
In environments where the log is not being
maintained, SQL Server automatically truncates and reuses the space in
the VLFs at the beginning of the log file as soon as it reaches the end
of the log file. This can occur as long as the VLFs at the beginning of
the log file do not contain the MinLSN. SQL Server assumes that the log
is not being maintained when the database is in simple recovery mode, or
when you have never performed a full backup of the database.
If the database is configured to use the bulk-logged
or full recovery models so that the log is being maintained, the
reusable portion of the log prior to the MinLSN cannot be truncated or
purged until the transaction log has actually been backed up.
If the first VLF cannot be reused because it contains
the MinLSN or it hasn’t been truncated yet, SQL Server needs to expand
the log file. This is done by adding a new VLF to the end of the
physical log (as long as the log file is still configured to grow
automatically). SQL Server can then continue writing log records to the
new VLF. However, if the log file is not configured to auto-grow, a 9002
error is generated, indicating that the log file is out of space.
Certain conditions can cause log records to remain
active, preventing the MinLSN from moving out of the first VLF, which in
turn prevents the VLFs at the beginning of the physical log file from
being reused. Some of the conditions that can lead to the log space not
being reused include, but are not limited to, the following:
No checkpoint has taken place yet since the log was last truncated, and the log records are needed for database recovery.
A database or log backup is in progress.
A long-running transaction is still active.
Database mirroring is paused.
The
database is the primary database for transactional replication, and
transactions relevant to the publications have not yet been delivered to
the distribution database.
A database snapshot is being created .
If something is preventing the log from being
truncated, SQL Server 2008 provides information in the system catalogs
to determine what is preventing log truncation. This information is
available in the log_reuse_wait_desc column of the sys.databases catalog view, which you can display by using a query similar to the following:
select name, log_reuse_wait_desc
from sys.databases
where name = db_name()
When a log file is configured to auto-grow and there
is significant update activity against the database and the inactive
portion of the transaction log is not being truncated frequently enough
(or at all) to allow for the reuse of VLFs, the log file size can become
excessive. This can lead to insufficient disk space in the file system
that contains the log file. This can
subsequently also lead to a 9002 out-of-space error if the log file
needs to grow and not enough disk space is available. At times, you
might need to shrink the log file to reduce its size.
Shrinking the Log File
After the log has been backed up and the active
portion of the log has wrapped around to the beginning of the log file,
the VLFs at the end of the physical log can be deleted from the log
file, and the log file can be reduced in size.
When you shrink a log file, the space freed can only
come from the end of the log file. The unit of size reduction is the
size of the virtual log file. For example, if you have a 1GB log file
that has been divided into five 200MB virtual log files, the log file
can only be shrunk in 200MB increments. The file size can be reduced to
sizes such as 800MB or 400MB, but the file cannot be reduced to sizes
such as 333MB or 750MB.
SQL Server 2008 provides the DBCC SHRINKFILE command for shrinking the transaction log file. Its syntax is as follows:
DBCC SHRINKFILE ( { 'file_name' } { [,EMPTYFILE] | [,target_size ] } )
[ WITH NO_INFOMSGS ]
If no target size is specified for the DBCC SHRINKFILE
command, SQL Server removes as many of the inactive virtual log files
from the end of the physical log file as possible to restore the
transaction log file to its default size. The default size of the
transaction log file is the size specified when the log file was created
or the last size set by using the ALTER DATABASE command.
If a target size is specified for DBCC SHRINKFILE,
SQL Server attempts to remove as many VLFs from the end of the log file
as possible to reduce the log file to as close to the target size as
possible without making the log smaller than the specified target size.
After shrinking, the log file is typically somewhat larger than the
target size, especially if the target size is not a multiple of the VLF
size.
If no VLFs beyond the target_size mark contain an active portion of the log, all the VLFs that come after the target_size mark are freed, and the DBCC SHRINKFILE statement completes successfully, with no messages. However, if any VLF beyond the target_size
mark does contain an active portion of the log, SQL Server frees from
the end of the physical log file as many of the VLFs as possible that do
not contain active portions of the log. When this occurs, the DBCC SHRINKFILE
command returns an informational message indicating that not all the
requested space was freed. When the active portion of the log moves off
the VLF(s) at the end of the physical log file, you can reissue the DBCC SHRINKFILE statement again to free the remaining space.
You can also use SQL Server Management Studio (SSMS) to shrink the transaction log file. In the Object Browser, expand the Databases folder and right-click the target database. Then select Tasks, Shrink, and Files. The Shrink File dialog appears, as shown in Figure 7.
In the File Type drop-down
list, select Log. To shrink the log file to its default size, click the
radio button next to Release Unused Space in the Shrink Action area of
the dialog box. To shrink the log file to a desired size, click the
radio button next to Reorganize Pages Before Releasing Unused Space and
specify the desired target size. After you choose the desired shrink
option, click OK.
In addition to manually shrinking the transaction log, SQL Server also provides a database option, AUTO_SHRINK,
that can be enabled to shrink the log and database files automatically
when space is available at the end of the file. If you are regularly
backing up or truncating the log, the AUTO_SHRINK option keeps
the size of the log file in check. The auto-shrink process runs
periodically and determines whether the log file can be shrunk. The Log
Manager keeps track of how much log space has been used since the
auto-shrink process last ran. The auto-shrink process then shrinks the
log either to 125% of the maximum log space used since auto-shrink last
ran or the default size of the transaction log file, whichever is
larger.
Tip
Repeated
growing and shrinking of the log file can lead to excessive file
fragmentation, which can have an adverse impact on the file I/O
performance. It is recommended that instead of using AUTO_SHRINK,
you set the transaction log to the size it is expected to grow to
during normal processing and enable the auto-grow option so that it
doesn’t run out of space if something prevents the log from being
truncated. By doing so, you help avoid the need for the log file to be
constantly expanded during normal processing and also avoid excessive
fragmentation of the log file. If something causes the log file to
auto-grow and exceed the normal log file size, you can always manually
shrink the file back to its normal size.