Thursday, December 21, 2017

Is Database Mirroring Causing The Transaction Log To Fill Up

Database Mirroring is a feature to increase database availability by setting up a principal database and a mirrored database.  When the principal database goes down, SQL Server will switch to the mirrored database to minimize down time for critical databases. 
In this article, I will describe some steps a DBA can take to check for mirroring on SQL Server, give a status of the mirroring state and some options for resolving any problems with the transaction log that might be caused by Database Mirroring.
First, a high level introduction to Database Mirroring in SQL Server.  Basically, there is a Principal database where your connections and applications are pointed. Then there is a Mirrored database that is a copy of the principal database, which is ready to take over just in case the principal database goes down.  Optionally, there is a third server that acts as a Witness to the communications between the principal and mirror databases when enabling the Automatic Failover option.
Every insert, update, and delete operation that occurs on the principal database is sent to the mirror database through active transaction log records.  The mirror server applies these log records in sequence as quickly as possible.  There are two operating modes that dictate how SQL Server manages the way the principal and mirrored databases handle the transactions. 
The first operating mode is high-performance (asynchronous) mode, where there is just a principal server and a mirror server.  In this mode, performance is priority at the risk of a potential loss of data and high availability.   What’s important to note here is that in this mode once the principal server sends the log for a transaction to the mirror, it does not wait for a confirmation from the mirror acknowledging the transacation.  In this case, the principal will just keep sending log data to the mirror regardless of the work load. 
The second operating mode is High Safety failover (synchronous) mode. In this mode, all committed transactions are guaranteed to be written to disk on the mirror server.  The principal database will send the transactions over to the mirror and wait to commit those transactions until it gets a verification from the mirror server.  If for some reason, the link between the two databases is affected, the transaction log will continue to grow on the principal database until it receives acknowledgement from the mirrored database. As a result the transaction log will grow and not re-use space. 
For the following examples, I setup a simple database called DBA, and configured it for High-Safety failover mirroring using a witness server. For information on establishing Database Mirroring please refer to this link: http://msdn.microsoft.com/en-us/library/ms190941(v=sql.110).aspx.   In addition, I created a small script that inserts data into a table to fill up the transaction log. 
First, I want to make sure that the database is indeed being mirrored.  For this I can query the sys.database_mirroring catalog view on the principal server.  The view will return rows for all of the databases on the server, however only the mirrored databases will return data, the non-mirrored databases will contain Null values.  
Use master
Go

SELECT
     d.name
    ,m.mirroring_state_desc
    ,m.mirroring_role_desc
    ,m.mirroring_safety_level_desc
    ,m.mirroring_partner_instance AS 'Mirror Server'
    ,m.mirroring_witness_name AS 'Witness Server'
    FROM
    sys.database_mirroring m
    INNER JOIN 
    sys.databases d
    ON 
    m.database_id = d.database_id
The results below tell me that my DBA database is setup for mirroring along with the name of the Mirrored Server and the name of the Witness server. The results also tell me that the database is currently synchronized with the mirror and everything is looking good.

Once I know the database is being mirrored I can also execute a system stored procedure to view the mirroring stare and status.  
EXEC sp_dbmmonitorresults 'DBA',2,1
When I execute this, it will return the following information, showing me the mirroring state of 4 (synchronized).  The mirroring_state column returns int values from 0-4 for the mirrored database, where 0 is suspended, 1 is disconnected, 2 is synchronizing, 3 is pending failover and 4 is synchronized.  You can refer to the MSDN article for a detailed explanation at http://msdn.microsoft.com/en-us/library/ms366320(v=sql.110).aspx .
So far, everything is looking good and we have no problems. 
What if the mirroring is paused or the mirror server is down and unable to process the logs sent from the principal.  At this point the principal is holding on to the transactions, waiting to hear from the mirror.  As a result the log is growing and unable to reuse any space. 
The first thing I can do is check the log_reuse_wait_desc column in sys.databases catalog view in the master database using the following query.
  SELECT
        name
    ,   recovery_model_desc
    ,   log_reuse_wait_desc
    FROM
        sys.databases
The results for my DBA database show that the database is waiting for a log backup.  
We run a log backup, and run the query again. Now we see the wait is DATABASE_MIRRORING
Ok, so now I know that the principal database is waiting to send transactions to the mirrored database. What is the state of mirroring on my server?
Going to the database properties mirroring page, I can see that mirroring is paused or suspended, as shown below.
I can also execute the sp_dbmmonitorresults system stored procedure again to see that the mirroring_state is at 0 or Suspended. It also shows the size of unsent_log in kb.
EXEC sp_dbmmonitorresults 'DBA',2,1
Now I can see that the log is waiting for database mirroring.  At this point, I  can change the status of mirroring or remove mirroring a couple of different ways.
First, under the Database properties Mirroring page there are options to Resume mirroring or to remove it .
It will switch the status to Synchronizing and will begin to transfer the data.
Click on Refresh and it will update to Synchronized 
Or, I can use the Alter Database command. This will resume the mirroring session.
ALTER DATABASE DBA SET PARTNER RESUME;
On the other hand, I can turn off mirroring by running the following command
ALTER DATABASE DBA SET PARTNER OFF;
Querying sys.databases again, I can see that the log_reuse_wait is back at NOTHING
There are a number of reasons why a transaction log continues to grow, in this article my focus was to provide some solutions to clear the log when database mirroring may be the cause. 
Proactive alerts and warnings can be set for mirroring to avoid these potential problems.  There is a white paper on Alerting on Database Mirroring Events (http://technet.microsoft.com/library/Cc966392 ) that goes into detail on configuring and setting up alerts. 

References

Tuesday, December 19, 2017

SQL Server Transaction Log Architecture and Management Guide

Every SQL Server database has a transaction log that records all transactions and the database modifications that are made by each transaction. The transaction log is a critical component of the database and, if there is a system failure, the transaction log might be required to bring your database back to a consistent state. This guide provides information about the physical and logical architecture of the transaction log. Understanding the architecture can improve your effectiveness in managing transaction logs.

Transaction Log Logical Architecture

The SQL Server transaction log operates logically as if the transaction log is a string of log records. Each log record is identified by a log sequence number (LSN). Each new log record is written to the logical end of the log with an LSN that is higher than the LSN of the record before it. Log records are stored in a serial sequence as they are created. Each log record contains the ID of the transaction that it belongs to. For each transaction, all log records associated with the transaction are individually linked in a chain using backward pointers that speed the rollback of the transaction.
Log records for data modifications record either the logical operation performed or they record the before and after images of the modified data. The before image is a copy of the data before the operation is performed; the after image is a copy of the data after the operation has been performed.
The steps to recover an operation depend on the type of log record:
  • Logical operation logged
    • To roll the logical operation forward, the operation is performed again.
    • To roll the logical operation back, the reverse logical operation is performed.
  • Before and after image logged
    • To roll the operation forward, the after image is applied.
    • To roll the operation back, the before image is applied.
    Many types of operations are recorded in the transaction log. These operations include:
  • The start and end of each transaction.
  • Every data modification (insert, update, or delete). This includes changes by system stored procedures or data definition language (DDL) statements to any table, including system tables.
  • Every extent and page allocation or deallocation.
  • Creating or dropping a table or index.
    Rollback operations are also logged. Each transaction reserves space on the transaction log to make sure that enough log space exists to support a rollback that is caused by either an explicit rollback statement or if an error is encountered. The amount of space reserved depends on the operations performed in the transaction, but generally it is equal to the amount of space used to log each operation. This reserved space is freed when the transaction is completed.
    The section of the log file from the first log record that must be present for a successful database-wide rollback to the last-written log record is called the active part of the log, or the active log. This is the section of the log required to a full recovery of the database. No part of the active log can ever be truncated. The log sequence number (LSN) of this first log record is known as the minimum recovery LSN (MinLSN).

Transaction Log Physical Architecture

The transaction log in a database maps over one or more physical files. Conceptually, the log file is a string of log records. Physically, the sequence of log records is stored efficiently in the set of physical files that implement the transaction log. There must be at least one log file for each database.
The SQL Server Database Engine divides each physical log file internally into a number of virtual log files (VLFs). Virtual log files have no fixed size, and there is no fixed number of virtual log files for a physical log file. The Database Engine chooses the size of the virtual log files dynamically while it is creating or extending log files. The Database Engine tries to maintain a small number of virtual files. The size of the virtual files after a log file has been extended is the sum of the size of the existing log and the size of the new file increment. The size or number of virtual log files cannot be configured or set by administrators.
Note
VLF creation follows this method:
  • If the next growth is less than 1/8 of current log physical size, then create 1 VLF that covers the growth size (Starting with SQL Server 2014)
  • If growth is less than 64MB, create 4 VLFs that cover the growth size (e.g. for 1 MB growth, create four 256KB VLFs)
  • If growth is from 64MB up to 1GB, create 8 VLFs that cover the growth size (e.g. for 512MB growth, create eight 64MB VLFs)
  • If growth is larger than 1GB, create 16 VLFs that cover the growth size (e.g. for 8 GB growth, create sixteen 512MB VLFs)
The only time virtual log files affect system performance is if the physical log files are defined by small size and growth_incrementvalues. The size value is the initial size for the log file and the growth_increment value is the amount of space added to the file every time new space is required. If the log files grow to a large size because of many small increments, they will have many virtual log files. This can slow down database startup and also log backup and restore operations. We recommend that you assign log files a size value close to the final size required, and also have a relatively large growth_increment value. For more information about these parameters, see ALTER DATABASE File and Filegroup Options (Transact-SQL).
The transaction log is a wrap-around file. For example, consider a database with one physical log file divided into four virtual log files. When the database is created, the logical log file begins at the start of the physical log file. New log records are added at the end of the logical log and expand toward the end of the physical log. Log truncation frees any virtual logs whose records all appear in front of the minimum recovery log sequence number (MinLSN). The MinLSN is the log sequence number of the oldest log record that is required for a successful database-wide rollback. The transaction log in the example database would look similar to the one in the following illustration.
tranlog3
When the end of the logical log reaches the end of the physical log file, the new log records wrap around to the start of the physical log file.
tranlog4
This cycle repeats endlessly, as long as the end of the logical log never reaches the beginning of the logical log. If the old log records are truncated frequently enough to always leave sufficient room for all the new log records created through the next checkpoint, the log never fills. However, if the end of the logical log does reach the start of the logical log, one of two things occurs:
  • If the FILEGROWTH setting is enabled for the log and space is available on the disk, the file is extended by the amount specified in the growth_increment parameter and the new log records are added to the extension. For more information about the FILEGROWTH setting, see ALTER DATABASE File and Filegroup Options (Transact-SQL).
  • If the FILEGROWTH setting is not enabled, or the disk that is holding the log file has less free space than the amount specified in growth_increment, an 9002 error is generated. Refer to Troubleshoot a Full Transaction Log for more information.
    If the log contains multiple physical log files, the logical log will move through all the physical log files before it wraps back to the start of the first physical log file.

Log Truncation

Log truncation is essential to keep the log from filling. Log truncation deletes inactive virtual log files from the logical transaction log of a SQL Server database, freeing space in the logical log for reuse by the physical transaction log. If a transaction log were never truncated, it would eventually fill all the disk space that is allocated to its physical log files. However, before the log can be truncated, a checkpoint operation must occur. A checkpoint writes the current in-memory modified pages (known as dirty pages) and transaction log information from memory to disk. When the checkpoint is performed, the inactive portion of the transaction log is marked as reusable. Thereafter, the inactive portion can be freed by log truncation. For more information about checkpoints, see Database Checkpoints (SQL Server).
The following illustrations show a transaction log before and after truncation. The first illustration shows a transaction log that has never been truncated. Currently, four virtual log files are in use by the logical log. The logical log starts at the front of the first virtual log file and ends at virtual log 4. The MinLSN record is in virtual log 3. Virtual log 1 and virtual log 2 contain only inactive log records. These records can be truncated. Virtual log 5 is still unused and is not part of the current logical log.
tranlog2
The second illustration shows how the log appears after being truncated. Virtual log 1 and virtual log 2 have been freed for reuse. The logical log now starts at the beginning of virtual log 3. Virtual log 5 is still unused, and it is not part of the current logical log.
tranlog3
Log truncation occurs automatically after the following events, except when delayed for some reason:

Write-Ahead Transaction Log

This section describes the role of the write-ahead transaction log in recording data modifications to disk. SQL Server uses a write-ahead logging (WAL) algorithm, which guarantees that no data modifications are written to disk before the associated log record is written to disk. This maintains the ACID properties for a transaction.
To understand how the write-ahead log works, it is important for you to know how modified data is written to disk. SQL Server maintains a buffer cache into which it reads data pages when data must be retrieved. When a page is modified in the buffer cache, it is not immediately written back to disk; instead, the page is marked as dirty. A data page can have more than one logical write made before it is physically written to disk. For each logical write, a transaction log record is inserted in the log cache that records the modification. The log records must be written to disk before the associated dirty page is removed from the buffer cache and written to disk. The checkpoint process periodically scans the buffer cache for buffers with pages from a specified database and writes all dirty pages to disk. Checkpoints save time during a later recovery by creating a point at which all dirty pages are guaranteed to have been written to disk.
Writing a modified data page from the buffer cache to disk is called flushing the page. SQL Server has logic that prevents a dirty page from being flushed before the associated log record is written. Log records are written to disk when the transactions are committed.

Transaction Log Backups

This section presents concepts about how to back up and restore (apply) transaction logs. Under the full and bulk-logged recovery models, taking routine backups of transaction logs (log backups) is necessary for recovering data. You can back up the log while any full backup is running. For more information about recovery models, see Back Up and Restore of SQL Server Databases.
Before you can create the first log backup, you must create a full backup, such as a database backup or the first in a set of file backups. Restoring a database by using only file backups can become complex. Therefore, we recommend that you start with a full database backup when you can. Thereafter, backing up the transaction log regularly is necessary. This not only minimizes work-loss exposure but also enables truncation of the transaction log. Typically, the transaction log is truncated after every conventional log backup.
We recommend taking frequent enough log backups to support your business requirements, specifically your tolerance for work loss such as might be caused by a damaged log drive. The appropriate frequency for taking log backups depends on your tolerance for work-loss exposure balanced by how many log backups you can store, manage, and, potentially, restore. Taking a log backup every 15 to 30 minutes might be enough. If your business requires that you minimize work-loss exposure, consider taking log backups more frequently. More frequent log backups have the added advantage of increasing the frequency of log truncation, resulting in smaller log files.
To limit the number of log backups that you need to restore, it is essential to routinely back up your data. For example, you might schedule a weekly full database backup and daily differential database backups.

The Log Chain

A continuous sequence of log backups is called a log chain. A log chain starts with a full backup of the database. Usually, a new log chain is only started when the database is backed up for the first time or after the recovery model is switched from simple recovery to full or bulk-logged recovery. Unless you choose to overwrite existing backup sets when creating a full database backup, the existing log chain remains intact. With the log chain intact, you can restore your database from any full database backup in the media set, followed by all subsequent log backups up through your recovery point. The recovery point could be the end of the last log backup or a specific recovery point in any of the log backups. For more information, see Transaction Log Backups (SQL Server).
To restore a database up to the point of failure, the log chain must be intact. That is, an unbroken sequence of transaction log backups must extend up to the point of failure. Where this sequence of log must start depends on the type of data backups you are restoring: database, partial, or file. For a database or partial backup, the sequence of log backups must extend from the end of a database or partial backup. For a set of file backups, the sequence of log backups must extend from the start of a full set of file backups. For more information, see Apply Transaction Log Backups (SQL Server).

Restore Log Backups

Restoring a log backup rolls forward the changes that were recorded in the transaction log to re-create the exact state of the database at the time the log backup operation started. When you restore a database, you will have to restore the log backups that were created after the full database backup that you restore, or from the start of the first file backup that you restore. Typically, after you restore the most recent data or differential backup, you must restore a series of log backups until you reach your recovery point. Then, you recover the database. This rolls back all transactions that were incomplete when the recovery started and brings the database online. After the database has been recovered, you cannot restore any more backups. For more information, see Apply Transaction Log Backups (SQL Server).

Checkpoints and the Active Portion of the Log

Checkpoints flush dirty data pages from the buffer cache of the current database to disk. This minimizes the active portion of the log that must be processed during a full recovery of a database. During a full recovery, the following types of actions are performed:
  • The log records of modifications not flushed to disk before the system stopped are rolled forward.
  • All modifications associated with incomplete transactions, such as transactions for which there is no COMMIT or ROLLBACK log record, are rolled back.

Checkpoint Operation

A checkpoint performs the following processes in the database:
  • Writes a record to the log file, marking the start of the checkpoint.
  • Stores information recorded for the checkpoint in a chain of checkpoint log records.
    One piece of information recorded in the checkpoint is the log sequence number (LSN) of the first log record that must be present for a successful database-wide rollback. This LSN is called the Minimum Recovery LSN (MinLSN). The MinLSN is the minimum of the:
    • LSN of the start of the checkpoint.
    • LSN of the start of the oldest active transaction.
    • LSN of the start of the oldest replication transaction that has not yet been delivered to the distribution database.
      The checkpoint records also contain a list of all the active transactions that have modified the database.
  • If the database uses the simple recovery model, marks for reuse the space that precedes the MinLSN.
  • Writes all dirty log and data pages to disk.
  • Writes a record marking the end of the checkpoint to the log file.
  • Writes the LSN of the start of this chain to the database boot page.

Activities that cause a Checkpoint

Checkpoints occur in the following situations:
  • A CHECKPOINT statement is explicitly executed. A checkpoint occurs in the current database for the connection.
  • A minimally logged operation is performed in the database; for example, a bulk-copy operation is performed on a database that is using the Bulk-Logged recovery model.
  • Database files have been added or removed by using ALTER DATABASE.
  • An instance of SQL Server is stopped by a SHUTDOWN statement or by stopping the SQL Server (MSSQLSERVER) service. Either action causes a checkpoint in each database in the instance of SQL Server.
  • An instance of SQL Server periodically generates automatic checkpoints in each database to reduce the time that the instance would take to recover the database.
  • A database backup is taken.
  • An activity requiring a database shutdown is performed. For example, AUTO_CLOSE is ON and the last user connection to the database is closed, or a database option change is made that requires a restart of the database.

Automatic Checkpoints

The SQL Server Database Engine generates automatic checkpoints. The interval between automatic checkpoints is based on the amount of log space used and the time elapsed since the last checkpoint. The time interval between automatic checkpoints can be highly variable and long, if few modifications are made in the database. Automatic checkpoints can also occur frequently if lots of data is modified.
Use the recovery interval server configuration option to calculate the interval between automatic checkpoints for all the databases on a server instance. This option specifies the maximum time the Database Engine should use to recover a database during a system restart. The Database Engine estimates how many log records it can process in the recovery interval during a recovery operation.
The interval between automatic checkpoints also depends on the recovery model:
  • If the database is using either the full or bulk-logged recovery model, an automatic checkpoint is generated whenever the number of log records reaches the number the Database Engine estimates it can process during the time specified in the recovery interval option.
  • If the database is using the simple recovery model, an automatic checkpoint is generated whenever the number of log records reaches the lesser of these two values:
    • The log becomes 70 percent full.
    • The number of log records reaches the number the Database Engine estimates it can process during the time specified in the recovery interval option.
For information about setting the recovery interval, see Configure the recovery interval Server Configuration Option.
Tip
The -k SQL Server advanced setup option enables a database administrator to throttle checkpoint I/O behavior based on the throughput of the I/O subsystem for some types of checkpoints. The -k setup option applies to automatic checkpoints and any otherwise unthrottled checkpoints.
Automatic checkpoints truncate the unused section of the transaction log if the database is using the simple recovery model. However, if the database is using the full or bulk-logged recovery models, the log is not truncated by automatic checkpoints. For more information, see The Transaction Log.
The CHECKPOINT statement now provides an optional checkpoint_duration argument that specifies the requested period of time, in seconds, for checkpoints to finish. For more information, see CHECKPOINT.

Active Log

The section of the log file from the MinLSN to the last-written log record is called the active portion of the log, or the active log. This is the section of the log required to do a full recovery of the database. No part of the active log can ever be truncated. All log records must be truncated from the parts of the log before the MinLSN.
The following illustration shows a simplified version of the end-of-a-transaction log with two active transactions. Checkpoint records have been compacted to a single record.
active_log
LSN 148 is the last record in the transaction log. At the time that the recorded checkpoint at LSN 147 was processed, Tran 1 had been committed and Tran 2 was the only active transaction. That makes the first log record for Tran 2 the oldest log record for a transaction active at the time of the last checkpoint. This makes LSN 142, the Begin transaction record for Tran 2, the MinLSN.

Long-Running Transactions

The active log must include every part of all uncommitted transactions. An application that starts a transaction and does not commit it or roll it back prevents the Database Engine from advancing the MinLSN. This can cause two types of problems:
  • If the system is shut down after the transaction has performed many uncommitted modifications, the recovery phase of the subsequent restart can take much longer than the time specified in the recovery interval option.
  • The log might grow very large, because the log cannot be truncated past the MinLSN. This occurs even if the database is using the simple recovery model, in which the transaction log is generally truncated on each automatic checkpoint.

Replication Transactions

The Log Reader Agent monitors the transaction log of each database configured for transactional replication, and it copies the transactions marked for replication from the transaction log into the distribution database. The active log must contain all transactions that are marked for replication, but that have not yet been delivered to the distribution database. If these transactions are not replicated in a timely manner, they can prevent the truncation of the log. For more information, see Transactional Replication.

Additional Reading

We recommend the following articles and books for additional information about the transaction log.

Managing Transaction Logs in SQL Server

The Transaction Log provides the means by which either the complete set of tasks of a database transaction are performed or none of them are. It ensures that , via rollback, only valid data is written out to the database, and it allows transactions to be played back to recreate the system state right before a failure. Robert Sheldon explains the various basic tasks involved in managing the transaction log.
Each database in a SQL Server instance has a log that records all database modifications. Because this log is written independently, before the modifications take place, the transaction log enables the database to roll back or restore transactions in the event of hardware failure or application error.  Because of the importance of its role, the transaction log is stored in one or more log files that are separate from the data files; the log records are written to the transaction log before the modified contents in the buffer cache are written to the data files.
For each database, the transaction log can support any of the following operations:
  • Rolling back individual transactions if a ROLLBACK statement is issued or the database engine detects an error.
  • Rolling back incomplete transactions that result from server failure. The transactions are rolled back when SQL Server is restarted.
  • Recovering incomplete transactions written to the logs but not to the data files as a result of server failure. The transactions are written to the data files when SQL Server is restarted.
  • Rolling forward a restored database, filegroup, file, or page to the point of failure in the event of hardware failure. The transactions are rolled forward after the latest full and differential backups are applied.
  • Supporting transactional replication, database mirroring, and log shipping.
The file (or files, if more than one file is used) that makes up the transaction log are divided into virtual log files whose size, along with their quantity in the physical log, is determined by the database engine. The database engine also decides when, and which, virtual files get truncated. You can, however, specify the minimum and maximum sizes of the physical log, as well as configure the growth increments used when expanding that file. In addition, you can add physical files to the log, delete files, increase the size of the log, and shrink the log.
In this article, I explain how to perform these tasks so you can begin to manage your transaction logs, and I provide examples that demonstrate each how each task works. For these examples, I used the following code to create the EmployeeDB database on a local instance of SQL Server 2008:
Notice that I created the database files in a location other than the default used by SQL Server. If you run this code, you can locate the database files wherever you think is appropriate. After I created the database, I used the following SELECT…INTO statement to retrieve data from the AdventureWorks2008 database and create the Employees table:
You do not have to use this code to perform the examples in this database, but it does help to have a small test database that you can experiment with as you learn about transaction logs. If you plan to use a database other than the one shown here, simply insert the database name, where appropriate, in the code samples I provide.

Configuring the Recovery Model

Each SQL Server database includes the Recovery Model property, which determines how transactions are logged, whether the transaction log can be backed up, and the type of restore operations permitted. By default, a new database inherits the recovery model from the model database. However, you can override the default setting by assigning a different recovery model.
You can configure a SQL Server database with any one of the following three recovery models.
  • Simple: In this model, transaction log backups are not permitted, which means you do not have the administrative overhead associated with maintaining transaction log backups. The model also automatically reclaims log space, so there is almost no need to manage the transaction log space. However, this is also the riskiest of the models-a database can be restored only to the point of its last backup. Transactions that have been performed since the last backup are lost. This model is generally used for the system databases, and for both testing and development, although it is sometimes appropriate for a read-only database such as a data warehouse. In this model, some operations are only minimally logged.
  • Full: The log files can and should be backed up, as they provide full recoverability to a specific point in time. However, this model is less risky than the Simple model. In the Full recovery model, all operations are fully logged, including bulk import operations. The Full recovery model is generally the model used for production environments.
  • Bulk Logged: This model is intended as an adjunct to the Full recovery model because operations such as bulk import are only minimally logged. For example, you might want to bulk load data and you’re not concerned about logging these transactions because you can reload the data if necessary. In such cases, you can set the recovery model to Bulk Logged while importing the data, and then change the setting back to Full when you are finished. (Note that you should perform a full backup after you change the setting back to Full.)
You can switch the recovery model on a database by running an ALTER DATABASE statement and specifying the SET RECOVERY clause, as shown in the following example:
As you can see, I am altering the EmployeeDB database and setting the recovery model to FULL. Note, however, that by default the model database is configured with the Full recovery model, which means that the EmployeeDB was automatically configured with the Full model because it inherited the setting from the model database. As a result, if the default recovery model wasn’t changed in the modeldatabase of your instance of SQL Server, the ALTER DATABASE example above did not change the setting. However, you should also note that if you switch a database from the Simple model to the Full model, there are other steps you must sometimes take, such as doing a full database backup. The topic “Considerations for Switching from the Simple Recovery Model” in SQL Server Books Online describes what steps you might need to take when switching from the Simple model to Full or Bulk Logged.
You can also set the recover model in SQL Server Management Studio. In Object Explorer, right-click the database name and then click Properties. In the Database Properties dialog box, click the Optionspage and then set the Recovery model property.

Monitoring the Log File

When maintaining a database’s transaction log, you’ll often want to retrieve information about the log so you can verify its settings or track how much log space is being used. One way to find information about the log is by using the sys.database_files catalog view. The view returns details about database files, including the type of file, the current size of the file, and how large the file is permitted to grow.
In the following example, I use the sys.database_files catalog view to retrieve data about the log file associated with the EmployeeDB database:
The statement returns the current size of the file (in 8-KB pages), the maximum size that the file is permitted to grow (also in 8_KB pages), the growth rate, and the is_percent_growth flag, which determines how the growth rate should be interpreted. If the flag is set to 0, the growth rate is the number of 8-KB pages. If the flag is set to 1, the growth rate is a percentage.
The above SELECT statement return results similar to the following:
As the results show, the statement returns only one row. That’s because the EmployeeDB database has only one log file associated with it. The results also indicate that the current size of the EmployeeDB_log file is 128 8-KB pages. However, the file can grow to 268,435,456 8-KB pages at a growth increment of 10%.
You can also use the DBCC SQLPERF statement to return information about the transaction logs for each database in a SQL Server instance. To retrieve log data, you must specify the LOGSPACE keyword in parentheses, as shown in the following example:
The statement returns the log size in MB, the percentage of log space used, and the status of the log for every database on your SQL Server instance. The following results show the information that the DBCC SQLPERF statement returns for the EmployeeDB database:
In this case, the EmployeeDB log is about 1 MB in size, and about 40% of the log space is being used.
You can also generate a report in SQL Server Management Studio that graphically displays data similar to the results of the DBCC SQLPERF statement. To generate the report, right-click the name of the database in Object Explorer, then point to reports, next point to Standard Reports, and finally click Disk Usage.

Backing Up the Log File

If a database is configured with the Full or Bulk Logged recovery model, you should back up the transaction log regularly so it can be truncated to free up inactive log space. The backup can also be used (along with the database backups) to restore the database in the event of failure.
Before a log file can be backed up, a full database backup must be performed. For instance, before I back up the log file I am using for the examples in this article, I will run the following BACKUP DATABASE statement on the EmployeeDB database:
Note that, if you run this code, make sure the TO DISK location exists, or specify a different location.
After I backed up the database, I ran the following data modification statements so the log would contain transactions not included in the backup:
I then reran the DBCC SQLPERF statement to view the amount of log space being used. The statement returned the following results:
As you can see, the percentage of log space being used increased from about 40% to nearly 65%.
After the database has been backed up, you can back up the transaction log. To perform a transaction log backup, use the BACKUP LOG statement and specify the target destination for the backup files, as shown in the following example:
Note that, if you run this code, make sure the TO DISK location exists, or specify a different location.
Notice that I include the TO DISK clause to specify the file destination. However, the BACKUP statement supports other options for backing up data. See the topic “BACKUP (Transact-SQL)” in SQL Server Books Online for more information.
After you back up the transaction log, the SQL Server database engine automatically truncates inactive log space. (Truncating a log file removes inactive virtual log files, but does not reduce the file size. In addition, you cannot specifically truncate a log. You can, however, shrink the file, which does reduce the size. I explain how to shrink a log file later in the article). To verify whether the log has been truncated, run the DBCC SQLPERF statement again. This time, the results should be similar to the following:
Now the percentage of log space being used is back down around 45%.

Modifying a Log File

You can use the ALTER DATABASE statement to modify a log file. You must specify the MODIFY FILE clause, along with the appropriate options. In addition to specifying the logical name of the log file, you can define the following three arguments:
  • SIZE: The new size of the log file. You can specify the size as KB, MB, GB, or TB, such as 10 MB or 1 GB. If you do not specify a size when you add the file, the database engine uses the default size of 1 MB. The new size must be greater than the current size, otherwise you’ll receive an error when you run the statement.
  • MAXSIZE: The maximum size that the file can grow to. You can specify the size as KB, MB, GB, or TB. If you do not specify a maximum size, the file will grow until it fills the disk (assuming the space is needed).
  • FILEGROWTH: The growth increment used when expanding the file. You can specify the size as KB, MB, GB, or TB, or you can specify the size as a percentage, such as 10%. If a number is specified without a suffix, MB is used. If no number is specified, 10% is used. A value of 0 indicates that no automatic growth is allowed.
The following ALTER DATABASE statement modifies the EmployeeDB_log file in the EmployeeDB database:
As the statement shows, after I specify the logical name of the log file, I set the new size for the file (2 MB), the maximum size (200 MB), and the growth increment (10 MB).
After you run the ALTER DATABASE statement, you can they query the sys.database_files catalog view, to verify the changes. Your results should be similar to the following:
The file size is now 256 8-KB pages, the maximum size is 25,600 8-KB pages, and the growth increment is 1,280 8-KB pages.

Shrinking a Log File

As you’ll recall, in order to truncate the transaction log, you must first back up the log. The database engine then automatically truncates the inactive records. However, truncating the log doesn’t reduce its size. Instead, you must shrink the log file, which removes one or more inactive virtual log files.
To shrink a log file, you can run a DBCC SHRINKFILE statement that specifies the name of the log file and the target size, in MB. For example, the following DBCC SHRINKFILE statement shrinks the EmployeeDB_log file:
The target size in this statement is 1 MB (128 8-KB pages). When you run the statement, the database engine will shrink the file down to that size, but only if there are enough inactive virtual log files.
After you run the statement, you can verify the extent to which a file was reduced by querying the sys.database_files catalog view, which should return results similar to the following:
As you can see, the size has been reduced from 256 8-KB pages to 128. If the database engine cannot free up the space, it issues a message that suggests steps you can take to free up log space. Follow the suggested steps and then rerun the DBCC SHRINKFILE statement.

Adding or Deleting a Log File

If you need to enlarge your transaction log, one method you can use is to add a file to the log.
You can do this by using the ADD LOG FILE clause of the ALTER DATABASE statement. In addition to specifying the logical and physical names of the new log file, you can define the following three arguments:
  • SIZE: The initial size of the log file. You can specify the size as KB, MB, GB, or TB, such as 10 MB or 1 GB. If you do not specify a size when you add the file, the database engine uses the default size of 1 MB.
  • MAXSIZE: The maximum size that the file can grow to. You can specify the size as KB, MB, GB, or TB. If you do not specify a maximum size, the file will grow until it fills the disk (assuming the space is needed).
  • FILEGROWTH: The growth increment used when expanding the file. You can specify the size as KB, MB, GB, or TB, or you can specify the size as a percentage, such as 10%. If a number is specified without a suffix, MB is used. If no number is specified, 10% is used. A value of 0 indicates that no automatic growth is allowed.
The following example adds the EmployeeDB_log2 file to the EmployeeDB transaction log:
Notice that I first specify the logical and physical file names, and then define the initial size, maximum size, and growth increment. After I run this statement, I can confirm that the file has been added to the log by querying the sys.database_files catalog view (using the same query as I used previously), which returns the following results:
As the results indicate, the EmployeeDB_log2 file has been added to the database with an initial size of 256 8-KB pages, a maximum size of 6,400 8-KB pages, and a growth increment of 10%.
You can also use the ALTER DATABASE statement to remove a log file by specifying the REMOVE FILE clause, as shown in the following example:
To determine whether the file has been removed, you can once again query the sys.database_files catalog view, which returns the following results:
Notice that the EmployeeDB_log2 file is still listed, but the size has been set to 1 8-KB page. The physical file has been deleted, but the logical file is still associated with the database. You must back up the transaction log before the logical file is removed. After you back up the log, you can again query the sys.database_files catalog view. This time your results should look similar to the following:
As you can see, the logical file has been removed.

Conclusion

Clearly, transaction logs play an important role in SQL Server databases, and the information above should provide you with an introduction on how to work with them. What I have not covered, however, are the ways that the transaction log is used to support transactional replication, database mirroring, and log shipping. I also have not covered how to use the transaction log and its backups to restore a database. These topics each deserve their own article. But you should at least now have a basic foundation in transaction logs and be able to start working with them. However, I highly recommend that you check out the various topics in SQL Server Books Online on transaction logs as well as other sources on the subject so you have a complete picture of how the logs work and how they’re best managed.