One of the most important components of Exchange server is the transaction logs. Exchange server was designed to write all transactions to these log files and commit the changes to the databases when the system allows. Users can send and receive messages without touching the database thanks to this write-ahead method of logging.
When a message is sent, the transaction is first recorded in the transaction logs. Until the transaction is committed to the Exchange database (EDB), the only existence of this data is in the system memory and the transaction logs. In the event of a crash, you lose the contents of the memory and all you are left with is the record in the transaction log. These transaction logs are crucial to the recovery of a failed Exchange server, whether it was a minor crash that required a reboot, or a more catastrophic failure requiring the deployment of your disaster recovery plans. The same goes for other transactions such as received messages, deleted items and messages moved to different folders.
For this reason, it is recommended to house the transaction files on a redundant storage system, like a RAID 1 array, so that in the event of a hardware failure, no data is lost. Losing a set of transaction logs will not prevent you from restoring from your backups, but you will lose all the messages and changes since the last full backup.
Understanding Message Headers
When an Exchange server is started, and the Microsoft Information Store (Store.exe) comes online. ESE checks the databases to determine whether they are in a consistent state or/and inconsistent state. This information is stored with a flag in the database header and signifies whether the store was shutdown cleanly (consistent) or if there are outstanding transactions in the transaction logs that have yet to be committed. If you want to determine if the database is in a consistent, or inconsistent, state you can use ESEUTIL and append the /MH switch which will check the database header and report the state.
C:\Program Files\Exchsrvr\bin\eseutil /mh “Path\to\file.edb”
Running this command you will see some important information on the state of the database (see Figure 1) as well as information on the backup state (see Figure 2).
Figure 1: Database State
Figure 2: Database Backup Timestamp
If ESE detects any inconsistency, it performs what is called a soft recovery. In a soft recovery, the transaction logs are replayed to locate any transaction not yet committed to the database. With multiple databases in a single Storage Group, the processing can be quite complex. All the databases in a storage group use the same set of transaction logs and it is possible that each database is in a different state of consistency. Luckily for administrators, ESE handles this all in the background without any administrator interaction required.
Viewing Transaction Logs
Opening a transaction log for viewing can be done with any text editor such as Notepad or WordPad, but there is not much human readable text. The majority of the transaction log is comprised of binary and non printable characters (see Figure 3).
Figure 3: Viewing Transaction Log
Not much to see, but that is not to say looking at a transaction log is completely useless as there is some useful information that can be found. If you scroll through a log file you can find header information (see Figure 4) and data, but because the transaction logs are limited to 5MB in size, the data can end up being spread over multiple transaction logs. As an example, let’s say that a user sends a 6MB Excel file; the first 500KB maybe written to a transaction log, filling it up and triggering the creation of a new log. This next log could be compromised of the next 5MB of the Excel file, and the rest of the data going into a third transaction log.
Figure 4: Message Headers
Along with the header information, you will also be able to see timestamps for when the log was created and a unique signature matching the transaction log to the database. The signature is important as it ensures transactions are committed to the proper database. If you tried to replay transactions to a different database the outcome could be disastrous.
Dumping Log Information
Just like when we used ESEUTIL with the /MH switch to view the state of the database, we can use the same tool with the /ML switch to dump the header information of a log file.
C:\Program Files\Exchsrvr\bin\eseutil /ml “Path\to\transaction.log”
Running this command will dump the header of the transaction log and allow us to garner some important information. Let’s look at the first half of the dump (see Figure 5) and what some of that data means and then we will look at the second half.
Figure 5: Log Header Information
Starting from the top we will see:
- Base name – The base name will show as e00 as that is the name of the log when it was generated. Once full, it is renamed and a new e00 log is generated.
- Log file – This is the current name and location of the log file.
- lGeneration – This is the generation number. In this example the number is 36307 meaning that there are 36306 previously generated logs.
- Checkpoint – This line specifies which position the checkpoint file (e00.chk) was in when this log was created. This example says NOT AVAILABLE which is not a concern as another log file will have this information.
- Creation time – This is the time when this log was created.
- Prev gen time – This is the time when the previous log was generated.
- Env Systempath – Specifies the location of the checkpoint file.
- Env LogFilePath – Specifies the location of the transaction logs.
- Signature – The ties the transaction log to a specific database.
- Circular logging – This information determines if circular logging is enabled or disabled.
One piece of information to note from this is the time between the Creation time and the Prev gen time. In this example the time difference is 49 minutes and 37 seconds, which tells us that this server is not under much load. If the time stamps were a lot closer together, this would indicate a server that is under load.
The second half of this dump file (see Figure 6) contains the database information. Each storage group has its own set of transaction logs and each storage group can contain multiple databases. This section of the log specifies which databases these log files belong too.
Figure 6: Database Associations
Transaction Log Best Practices
In order to maintain your transaction logs and a healthy Exchange server, there are some best practices you should follow.
- Perform regular full backups to commit the transactions and flush the logs.
- Transaction logs create a high write load and should be moved to a dedicated drive that can support a heavy write load.
- Protect transaction logs by placing them on a redundant array. RAID 1 is ideal for transaction logs. RAID 5 is not as write friendly and RAID 1+0 is overkill in most instances.
- Ensure there is enough room on the drive to contain all the transaction logs created between backups. If the drive runs out of room, the MTA will stop and Exchange will stop functioning.
- Do not place transaction logs on compressed drives as they will need to be decompressed whenever Exchange access them. This will slow the system down.
- Do not use circular logging except in cases where the Exchange server does not hold any mailboxes (i.e. NNTP servers).
For more information on working with transaction logs and Exchange server, check out these articles.