Bu makalede Virtual Log File sayısını mail ile bildirme konusunu ele almış olacağız. Virtual Log file adından da anlaşılacağı gibi sanal log dosyalarıdır. Bu sanal log dosyaları veritabanının ldf dosya uzantısının işletim sisteminizden disk alanı tahsis etmesi sonucu oluşmaktadır. Veritabanın işletim sisteminden ne kadar disk alan tahsis edeceği ve oluşan virtual log file sayısı veritabanına set edilen autogrowth değerine bağlıdır.
Birden fazla vlf oluşması sistemin restart olurken geç ayağa kalkmasına ve yoğun sistemlerde insert update delete işlemlerinde gecikmeye sebep olur. Herhangi bir restore işleminden sonra veritabanının geç ayağa kalkmasını sağlar. Çünkü içinde bulunan virtual log dosyalarını teker teker okur. Çok fazla VLF olduğunda: Backup/Restore yavaşlar. Database Recovery süresi uzar. Checkpoint, autogrow, log truncate gibi işlemler gecikir
Aşırı VLF Sayısı = Performans Sorunu
SORR YAPAY ZEKAYA VLF COUNT DEĞERLERİ DÜŞÜKSE SONUÇTA İN ACTİVE OLUYOR BACKUP İŞLEMLERİNDE SIKINTIYA SEBEBİYET VERMEZ.
Aşağıdaki komut sayesinde veritabanlarımızın üzerinde vlf count sayısını belirli bir değeri geçen veritabanları mail atan script görülmektedir. Bunun için database mail configuration yapısının olması gerekmektedir. İlgili makaleyi sayfada okuyabilirsiniz.
use DBAMON
go
CREATE PROCEDURE SendVLFReportAsHTML
AS
BEGIN
SET NOCOUNT ON;
DECLARE @tableHTML NVARCHAR(MAX);
DECLARE @subject NVARCHAR(255);
DECLARE @body NVARCHAR(MAX);
-- HTML tablosunu oluştur
SET @tableHTML =
N'<html><head>' +
N'<style>' +
N'table {border-collapse: collapse; width: 100%; font-family: Arial, sans-serif; border: 2px solid #333;}' +
N'th {background-color: #808080; color: white; padding: 12px; text-align: left; border: 1px solid #666;}' +
N'td {border: 1px solid #666; padding: 8px;}' +
N'tr:nth-child(even) {background-color: #f2f2f2;}' +
N'tr:hover {background-color: #ddd;}' +
N'.warning {color: #FF0000; font-weight: bold;}' +
N'</style>' +
N'</head><body>' +
N'<h2>SQL Server VLF (Virtual Log File) Raporu</h2>' +
N'<p><strong>Rapor Tarihi:</strong> ' + CONVERT(VARCHAR, GETDATE(), 104) + ' ' + CONVERT(VARCHAR, GETDATE(), 108) + '</p>' +
N'<p><strong>Sunucu:</strong> ' + @@SERVERNAME + '</p>' +
N'<table>' +
N'<tr>' +
N'<th>Database Name</th>' +
N'<th>Database ID</th>' +
N'<th>VLF Count</th>' +
N'<th>VLF Size (MB)</th>' +
N'<th>Active VLF</th>' +
N'<th>Active VLF Size (MB)</th>' +
N'<th>In-active VLF</th>' +
N'<th>In-active VLF Size (MB)</th>' +
N'</tr>';
-- Verileri HTML tablosuna ekle
DECLARE @name NVARCHAR(128), @database_id INT, @vlfCount INT,
@vlfSizeMB DECIMAL(18,2), @activeVLF INT, @activeVLFSizeMB DECIMAL(18,2),
@inactiveVLF INT, @inactiveVLFSizeMB DECIMAL(18,2);
DECLARE db_cursor CURSOR FOR
SELECT [name], s.database_id,
COUNT(l.database_id) AS 'VLF Count',
SUM(vlf_size_mb) AS 'VLF Size (MB)',
SUM(CAST(vlf_active AS INT)) AS 'Active VLF',
SUM(vlf_active*vlf_size_mb) AS 'Active VLF Size (MB)',
COUNT(l.database_id)-SUM(CAST(vlf_active AS INT)) AS 'In-active VLF',
SUM(vlf_size_mb)-SUM(vlf_active*vlf_size_mb) AS 'In-active VLF Size (MB)'
FROM sys.databases s
CROSS APPLY sys.dm_db_log_info(s.database_id) l
GROUP BY [name], s.database_id
HAVING COUNT(l.database_id) > 500
ORDER BY COUNT(l.database_id) DESC;
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @name, @database_id, @vlfCount, @vlfSizeMB,
@activeVLF, @activeVLFSizeMB, @inactiveVLF, @inactiveVLFSizeMB;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @tableHTML = @tableHTML +
N'<tr>' +
N'<td>' + @name + '</td>' +
N'<td>' + CAST(@database_id AS NVARCHAR(10)) + '</td>' +
N'<td class="warning">' + CAST(@vlfCount AS NVARCHAR(10)) + '</td>' +
N'<td>' + CAST(@vlfSizeMB AS NVARCHAR(20)) + '</td>' +
N'<td>' + CAST(@activeVLF AS NVARCHAR(10)) + '</td>' +
N'<td>' + CAST(@activeVLFSizeMB AS NVARCHAR(20)) + '</td>' +
N'<td>' + CAST(@inactiveVLF AS NVARCHAR(10)) + '</td>' +
N'<td>' + CAST(@inactiveVLFSizeMB AS NVARCHAR(20)) + '</td>' +
N'</tr>';
FETCH NEXT FROM db_cursor INTO @name, @database_id, @vlfCount, @vlfSizeMB,
@activeVLF, @activeVLFSizeMB, @inactiveVLF, @inactiveVLFSizeMB;
END
CLOSE db_cursor;
DEALLOCATE db_cursor;
SET @tableHTML = @tableHTML + N'</table>';
-- Eğer hiç kayıt yoksa bilgi mesajı ekle
IF @tableHTML LIKE '%<td class="warning">%'
BEGIN
SET @tableHTML = @tableHTML +
N'<br/><p class="warning">⚠️ Uyarı: VLF sayısı 500 den fazla olan veritabanları performans sorunlarına neden olabilir.</p>';
END
ELSE
BEGIN
SET @tableHTML = @tableHTML +
N'<br/><p>✅ VLF sayısı 500 den fazla olan veritabanı bulunamadı.</p>';
END
SET @tableHTML = @tableHTML + N'</body></html>';
-- Mail başlığını belirle
SET @subject = N'SQL Server VLF Raporu - ' + CONVERT(VARCHAR, GETDATE(), 104);
-- Mail gönder
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'SQLProfile', -- Mail profil adınızı girin
@recipients = 'dbayonetimi@xx.gov.tr', -- Alıcı e-posta adresini girin
@subject = @subject,
@body = @tableHTML,
@body_format = 'HTML';
END
GO

Bu makalede MSSQL Server Virtual Log file Sayısını Mail ile Bildirme yapısını görmüş olduk. Başka makalede görüşmek dileğiyle…
İmanlarına iman katsınlar diye müminlerin kalplerine güven indiren O’dur. Göklerin ve yerin orduları Allah’ındır. Allah bilendir, herşeyi hikmetle yapandır.(Fetih-4)