Monitoring Database Transaction Log on Microsoft SQL Server

Transaction log is a file with .ldf file extension that tracks every transaction performed on a database. It is an essential part of a database.
There are three recovery models a database can be set to, Simple, Bulk-logged and Full. These models define how the transaction log behaves.

In the Simple Recovery Model, transaction history is purged once the transaction is completed and a checkpoint is performed (typically, a checkpoint runs every minute).

Pros:

  • occupies the least storage space of the three models
  • minimizes maintenance

Cons:

  • no point-in-time restore

When the Bulk-logged Recovery Model is used, SQL Server minimally logs bulk data modifications and insert operations. This is intended for situations involving large inserts, data modifications or index operations, in which you want to avoid performance issues caused by transaction log writing operations.

Pros:

  • avoid performance issues during large inserts, updates, index building etc.

Cons:

  • no point-in-time restore

When the Full Recovery Model is set, every transaction is fully logged, for the purposes of restoring the database to a specific point in time. This model is used when the database can’t afford any data loss.

Pros:

  • point-in-time restore possible

Cons:

  • higher storage requirements
  • requires ongoing log size management and automated log backups

Useful Queries

List the Recovery Model for All Databases

SELECT name AS [Database Name],
recovery_model_desc AS [Recovery Model] FROM sys.databases
GO

Databases Recovery Model

 

List only databases in the FULL recovery model

SELECT name, recovery_model_desc FROM sys.databases where recovery_model_desc='FULL';

Full Recovery Model Databases

 

Size of the transaction log

DBCC SQLPERF(logspace)

The above is a DBCC (Database Console Command) that displays the current size of the transaction logs, along with the percentage of log space used for each database.

DBCC SQLPERF Output

We can combine this command with sys.master_files view to get all the relevant info in one place.

DECLARE @LogSpace TABLE (
DatabaseName sysname,
LogSizeMB float,
LogSpaceUsedPercent float,
Status int
);

INSERT INTO @LogSpace
EXEC ('DBCC SQLPERF(logspace)');

SELECT
ls.DatabaseName,
mf.name AS LogFileName,
ls.LogSizeMB,
ls.LogSpaceUsedPercent
FROM @LogSpace ls
JOIN sys.master_files mf
ON ls.DatabaseName = DB_NAME(mf.database_id)
WHERE mf.type_desc = 'LOG'
ORDER BY ls.LogSizeMB DESC;

Here, we create a temporary table variable @LogSpace containing all the necessary data for a clear view of the transaction logs sizes.

Temporary Table Variable with Sizes

 

Truncate the transaction log

Finally, if needed, we can truncate the transaction log. For databases using the full recovery model, the transaction log is truncated by running a transaction log backup. The preferred approach is to automate log backups.
For databases in the simple recovery model, we can do this ad hoc, using the query:

ALTER DATABASE DatabaseName SET RECOVERY SIMPLE
GO
ALTER DATABASE DatabaseName SET RECOVERY FULL
GO
USE DatabaseName
GO
DBCC SHRINKFILE(LogFileName, 1)
GO
ALTER DATABASE DatabaseName SET RECOVERY SIMPLE
GO

 

Monitor the size of transaction logs with custom Prometheus metrics

We can configure alerting for large transaction logs using Prometheus. The metrics get exported by windows_exporter, an exporter designed for Windows machines. Once exported to a text file, metrics get scraped by a Prometheus instance.
One of the requirements is a simple PowerShell script that exposes our custom metrics via the textfile collector. In this example, we name the metrics `transaction_logs_truncate_needed`.

The PowerShell script is located in C:\Program Files\windows_exporter\custom_scripts\SQLTransactionLogs.ps1

$dbLog = $null
$dbLog = Get-ChildItem -Path "C:\Program Files\Microsoft SQL Server\*\MSSQL\DATA" -Filter "*.ldf" -Recurse |
     Where-Object { $_.Length -gt 4096MB } |
     Select-Object -ExpandProperty Name
if ($dblog -ne $null) {
     Set-Content -Path 'C:\Program Files\windows_exporter\textfile_inputs\SQLtransactionlogs.prom' -Encoding Ascii -Value "transaction_logs_truncate_needed 1"
     }
     else {
     Set-Content -Path 'C:\Program Files\windows_exporter\textfile_inputs\SQLtransactionlogs.prom' -Encoding Ascii -Value "transaction_logs_truncate_needed 0"
     }

We create a scheduled task that runs the script every 6 hours, starting at 2:00 AM.

$taskname = "Prometheus SQLTransactionLogs Need Check"
$taskdescription = "expose metrics to the text file for Prometheus scraping"
$user = "MACHINE\user"
$action = New-ScheduledTaskAction -Execute 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -Argument '-File "C:\Program Files\windows_exporter\custom_scripts\SQLTransactionLogs.ps1"'
$trigger = New-ScheduledTaskTrigger -Once -At 02:00AM -RepetitionInterval (New-TimeSpan -Hours 6)
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Hours 1)
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $taskname -Description $taskdescription -Settings $settings -User $user -RunLevel Highest -Force
Start-ScheduledTask -TaskName 'Prometheus SQLTransactionLogs Need Check'

The PowerShell script outputs metrics to the .prom file located at C:\Program Files\windows_exporter\textfile_inputs\SQLtransactionlogs.prom. Depending on whether there is a log larger than 4 GB, the .prom file content is

transaction_logs_truncate_needed 1

or

transaction_logs_truncate_needed 0

respectively.

Once the metrics are scraped by Prometheus, an alert rule can be triggered. We use Alertmanager to handle alerts, and the rule we set is:

--------------------
groups:
- name: SQLTransactionLogs
  rules:
  - alert: TransactionLogsTruncateNeeded
    expr: transaction_logs_truncate_needed == 1
    for: 30s
    annotations:
      summary: Transaction logs on `{{ $labels.instance }}`
      description: "Transaction logs need check" 
      runbook_url: https://wiki.plus.hr/How+To+Truncate+Transaction+log+on+SQL+Server
    labels:
      severity: warning

Povezani članci

Odgovori