Sometimes it seems that the
transaction log has a life of its own. The space within the file seems
to grow and shrink without rhyme or reason. If you've felt this way,
you're not alone. This section should shed some light on why the
transaction log behaves as it does.
Inside the Transaction Log
The transaction log contains all the
transactions for a database. If the server crashes the transaction log,
both transactions that have been written are used for recovery by
rolling back uncommitted partial transactions and by completing any
transactions that were committed but not written to the data file.
Virtually, the log can be imagined as a
sequential list of transactions sorted by date and time. Physically,
however, SQL Server writes to different parts of the physical log file
in virtual blocks without a specific order. Some parts might be in use,
making other parts available, so the log reuses itself in a loose
round-robin fashion.
The Active and Inactive Divide
The transactions in the transaction log can be divided into two groups (see Figure 1):
- Active transactions: Uncommitted and not yet written to the data file
- Inactive transactions: All those transactions before the earliest active transaction
Because transactions are of varying duration, and
are committed at different times, it's likely that committed
transactions are in the active portion of the log. The active portion
does not merely contain all uncommitted transactions, but all
transactions since the start of the oldest uncommitted transaction. One
old uncommitted transaction can make the active portion appear
unusually large.
Transaction Checkpoints
Understanding how SQL Server uses
checkpoints in the transaction log is important to understanding how
the transaction log is backed up and emptied. Due to performance
reasons, every time a database page is modified in memory, it is not
written to disk immediately. SQL Server generates automatic checkpoints
to write the dirty database pages from memory to disk. The time
interval between automatic checkpoints is variable and depends on the
amount of modifications made to the database and the recovery interval
SQL Server configuration option. Checkpoints calculate the amount of
work that must be done to recover the database during a system restart.
A checkpoint also occurs under any of the following conditions:
- When an ALTER DATABASE command is used.
- When the SQL Server is shut down.
Note
If you used the SHUTDOWN WITH NOWAIT command to shut down SQL Server, then SQL Server shuts down without performing checkpoints in any database.
- A minimally logged operation is performed in the database.
- A database backup is performed.
- When an activity requiring database shutdown or database restart is performed.
- When the number of log entries exceeds the estimated amount of work required by the SQL Server's recovery interval configuration option.
- If the database is in simple recovery model and the transaction log becomes 70 percent full.
Checkpoints may be manually initiated with a CHECKPOINT command. Checkpoints perform the following activities:
- Marks the checkpoint spot in the transaction log
- Writes a checkpoint-log record, including the following:
- The oldest active transaction
- The oldest replication transaction that has not been replicated
- A list of all active transactions
- Information about the minimum work required to roll back the database
- Marks the space before the oldest uncommitted transaction in a database with simple recovery for reuse
- Writes all dirty data and log pages to disk
Basically, a checkpoint gets everything up to
date as best as it can and then records the current state of the
dividing line between active and inactive in the log.
Note
In SQL Server 2012 there is a new type
of checkpoint called an indirect checkpoint. This is actually a
database-level setting in which you can manually specify a custom
recovery point for a given database. By default the recovery interval
is 0, which means SQL Server performs checkpoints on that database
using the interval set by the recovery interval server option.
Backing Up the Transaction Log
Performing a transaction log backup is similar to performing a full or differential backup, with a few notable differences.
The T-SQL command is as follows:
BACKUP LOG AdventureWorks2012
TO DISK = ‘e:\AdventureWorks2012Backup.bak'
WITH
NAME = ‘AdventureWorks2012Backup';
Result:
Processed 2 pages for database ‘AdventureWorks2012', file
'AdventureWorks2012_Log' on file 2.
BACKUP LOG successfully processed 2 pages in 0.118 seconds (0.095
MB/sec).
The same media options apply to the transaction
log backup that apply to the database backup; in addition, two options
are transaction-log specific.
- NO_TRUNCATE\CONTINUE_AFTER_ERROR:
Used for backing up the tail of the log of a damaged database that is
offline and does not start. If the data files of a user database are
damaged, a tail log backup succeeds only if the transaction log files
are not damaged, the state of database supports tail log backup, and
the database does not contain any bulk logged operations.
- NORECOVERY: Used to back up the tail of the log of a database that is online, and you intend to perform RESTORE next.
If the data file of the user database and master
database is damaged and the transaction log is not damaged, to minimize
data loss you can still backup the tail of the transaction log as
follows:
1. Rename the transaction log file. Do not delete this file as you will be using it again later in this procedure.
2. Rebuild the master database with the command line setup.
For detailed instructions on how to do this see http://msdn.microsoft.com/en-us/library/dd207003.aspx#RebuildProcedure
3. Reapply any SQL Server updates or service packs that were previously applied.
4. Create a
new user database. The number of data and log files need to match the
files of the damaged database. The size of the files can be different.
5. Stop SQL Server.
6. Delete data files of the new database, and replace the log files with the original transaction log files.
7. Start SQL Server.
8. The new
database will fail to recover because you deleted the data file. Run
the following command to back up the tail of the log:
BACKUP LOG Databasename
TO DISK = ‘file location'
WITH NO_TRUNCATE;
Note
If only the data files of the user
database are damaged and the master database and transaction log file
of the user database are available, the tail of the log can be backed
up directly by running the preceding BACKUP LOG command with the NO_TRUNCATE option.
The transaction log cannot be backed up if any of the following conditions exist:
- The database uses a simple recovery model.
- The database uses a bulk-logged recovery model, a bulk-logged operation has been executed, and the database files are damaged.
- Database files have been added or removed.
- The database uses bulk-logged or full recovery model, and a full database backup has not been performed yet.
In any of these cases, perform a full database backup instead.
Truncating the Log
Updates and deletes might not increase
the size of a data file, but to the transaction log every transaction
of any type is simply more data. Left to its own devices, the
transaction log will continue to grow with every data modification.
The solution is to back up the inactive portion
of the transaction log and then remove it. By default, backing up the
transaction log also truncates the log .
Note
BACKUP LOG WITH NO_LOG and BACKUP LOG WITH TRUNCATE_ONLY
were discontinued in SQL Server 2008. To truncate the log, either take
regular transaction log backups or put the database in simple recovery
model.
The Transaction Log and Simple Recovery Model
When the database uses a simple
recovery model, the transaction log ensures that each committed
transaction is written to the data file, and that's it. When SQL Server
performs a checkpoint and the transaction log is truncated, the free
space of the transaction log fluctuates, but the minimum is the size of
the active portion of the transaction log.
Under the simple recovery model, performing a manual checkpoint truncates the log and frees the log space.
Note
Truncating the log marks the inactive
portion of the log for reuse and does not reduce the physical size of
the transaction log. To reduce the physical size you need to run DBCC SHRINKFILE to manually shrink the log file. There are many DBAs that run the DBCC SHRINKFILE command to shrink the log file right after the log backup. This action is highly discouraged because DBCC SHRINKFILE
can cause severe file-system fragmentation because the files will
likely need to grow again after they have been shrunk and cause
performance degradation. Instead, you must correctly size the
transaction log at the time of creation and perform frequent log
backups to keep the size in check.
Tip
To discover the operation preventing log truncation, use the log_reuse_wait_desc column of the sys.databases catalog view.