SQL Server’da Otomatik Yedekleme: Sıfırdan Üretime Hazır Script

Veritabanı yedeklemesi, bir sistem yöneticisinin yapabileceği en kritik işlemlerden biridir. Yedek almak yetmez — yedeğin çalışıp çalışmadığını doğrulamak, eski yedekleri düzenli temizlemek ve tüm bu süreci otomatize etmek de bir o kadar önemlidir.

Bu makalede SQL Server 2019 ve 2022 üzerinde test edilmiş, üretime hazır bir otomatik yedekleme scriptini adım adım açıklayacağım. Script; tam yedek alma, doğrulama, eski yedekleri silme ve SQL Agent Job olarak zamanlama konularını kapsamaktadır.

Gereksinimler

  • SQL Server 2019 veya 2022
  • SQL Server Management Studio (SSMS)
  • SQL Server Agent servisi çalışır durumda
  • Yedek klasörüne SQL Server servis hesabının yazma/silme yetkisi / yedekleme yapacağınız dosya özelliklerden SQL Server (MSSQLSERVER) hangi hesapla çalışıyorsa örn: DOMAIN\sqlsvc

1. Yedekleme Scripti

Scriptin temel mantığı şu adımlardan oluşur:

  1. Belirtilen veritabanlarını tek tek döngüyle yedekle
  2. Her yedeği RESTORE VERIFYONLY ile doğrula
  3. 5 günden eski yedekleri otomatik sil
  4. Hata oluşursa Job’ı fail et
USE msdb;
GO
-- 0. VARSA ESKİ JOB SİL
IF EXISTS (SELECT 1 FROM msdb.dbo.sysjobs WHERE name = N'FullDBBackup')
    EXEC msdb.dbo.sp_delete_job @job_name = N'FullDBBackup';
GO
-- KATEGORİ OLUŞTUR (yoksa)
IF NOT EXISTS (SELECT 1 FROM msdb.dbo.syscategories WHERE name = N'Database Maintenance')
    EXEC msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'Database Maintenance';
GO
-- 1. JOB OLUŞTUR
EXEC msdb.dbo.sp_add_job
    @job_name         = N'FullDBBackup',
    @enabled          = 1,
    @description      = N'Full DB backup + verify + retention',
    @owner_login_name = N'sa',
    @category_name    = N'Database Maintenance';
GO
-- 2. STEP EKLE
EXEC msdb.dbo.sp_add_jobstep
    @job_name         = N'FullDBBackup',
    @step_name        = N'Backup',
    @subsystem        = N'TSQL',
    @database_name    = N'master',
    @retry_attempts   = 2,
    @retry_interval   = 5,
    @output_file_name = N'E:\SQL_Backup\job_fullbackup.log',
    @flags            = 2,
    @command          = N'
DECLARE @name SYSNAME
DECLARE @path NVARCHAR(256) = ''E:\SQL_Backup\''
DECLARE @fileName NVARCHAR(400)
DECLARE @fileDate NVARCHAR(20)
DECLARE @retentionDays INT = 5
DECLARE @hasError BIT = 0
SET @fileDate = REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(19), GETDATE(), 120),''-'',''''),'' '',''_''),'':'','''')
DECLARE db_cursor CURSOR FAST_FORWARD FOR
SELECT name
FROM sys.databases
WHERE name IN (''ReportServer'',''DATABASE1'',''DATABASE2'',''DATABASE3'',''DATABASE4'',''DATABASE5'')
  AND state = 0
  AND is_read_only = 0;
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @fileName = @path + @name + ''_'' + @fileDate + ''.bak''
    BEGIN TRY
        BACKUP DATABASE @name
        TO DISK = @fileName
        WITH INIT, COMPRESSION, CHECKSUM, STATS = 10;
        RESTORE VERIFYONLY
        FROM DISK = @fileName
        WITH CHECKSUM;
        PRINT ''✔ BAŞARILI: '' + @name + '' → '' + @fileName;
    END TRY
    BEGIN CATCH
        PRINT ''✘ HATA: '' + @name + '' → '' + ERROR_MESSAGE();
        SET @hasError = 1;
    END CATCH;
    FETCH NEXT FROM db_cursor INTO @name
END
CLOSE db_cursor
DEALLOCATE db_cursor
BEGIN TRY
    DECLARE @deleteDate DATETIME
    SET @deleteDate = DATEADD(DAY, -@retentionDays, GETDATE())
    EXEC master.dbo.xp_delete_file
        0, @path, ''bak'', @deleteDate;
END TRY
BEGIN CATCH
    PRINT ''Silme hatası: '' + ERROR_MESSAGE();
END CATCH;
IF @hasError = 1
    THROW 50001, ''Backup hatası oluştu!'', 1;
';
GO
-- 3. SCHEDULE
EXEC msdb.dbo.sp_add_schedule
    @schedule_name     = N'HerGece2100',
    @enabled           = 1,
    @freq_type         = 4,
    @freq_interval     = 1,
    @active_start_time = 210000;
GO
EXEC msdb.dbo.sp_attach_schedule
    @job_name      = N'FullDBBackup',
    @schedule_name = N'HerGece2100';
GO
-- 4. SUNUCUYA BAĞLA
EXEC msdb.dbo.sp_add_jobserver
    @job_name    = N'FullDBBackup',
    @server_name = @@SERVERNAME;
GO
PRINT N'Job başarıyla oluşturuldu.'; -- boşluk kaldırıldı

2. Kullanılan Parametreler

ParametreAçıklama
COMPRESSIONYedek dosyasını sıkıştırır, disk tasarrufu sağlar
CHECKSUMYedek alınırken veri bütünlüğünü doğrular
INITHer çalışmada yeni dosya yazar
STATS = 10Her %10’da ilerleme mesajı gösterir
RESTORE VERIFYONLYYedeği geri yüklemeden okunabilirliğini test eder
xp_delete_filexp_cmdshell gerektirmeden eski dosyaları siler

3. Retention (Saklama Süresi) Mantığı

@retentionDays = 5 ayarlandığında, script her gece 21.00 da çalıştığında son 5 günün yedeği diskte saklanır, daha eskileri silinir.

4. SQL Agent Job Olarak Kurulum

SSMS GUI’si SSIS yüklü olmayan sistemlerde Job oluşturma ekranını açamayabilir. Bu durumda Job’ı tamamen T-SQL ile oluşturmak hem daha güvenilir hem de tekrarlanabilirdir.

Önemli Notlar

  • SSIS kurulu olmasa da bu script çalışır. SQL Agent Job’larında @subsystem = N'TSQL' kullandığınız sürece SSIS bağımlılığı yoktur.
  • xp_delete_file Microsoft tarafından resmi olarak belgelenmemiş bir prosedürdür ancak SQL Server 2008’den itibaren stabil şekilde çalışmaktadır ve xp_cmdshell gerektirmediği için tercih edilir.
  • Online backup olduğu için yedek sırasında kullanıcılar kesintisiz çalışmaya devam eder.
  • Script bir veritabanında hata alsa bile diğer veritabanlarını yedeklemeye devam eder. Tüm işlem tamamlandıktan sonra hata varsa Job fail olarak işaretlenir.

Kurulum oldukça basittir. sa kullanıcısı ile SQL Server’a login olduktan sonra New Query alanına tıklayın, scripti kopyalayın ve alt kısımdaki Execute butonuna basın. İşlem başarıyla tamamlandı mesajını gördükten sonra sol panelde SQL Server Agent → Jobs bölümüne gidin. Burada FullDBBackup adında yeni oluşan Job’u göreceksiniz. Üzerine sağ tıklayıp Start Job at Step seçeneğiyle scripti test edebilirsiniz.

Turuncu renk ile belirtiğim alanları kendinize database adlarınıza ve yedekleme sürücüsü yoluna göre düzenleyiniz.

Not: Job artık her gece belirlediğiniz saatte otomatik olarak çalışacaktır. 21.00

Sonuç

Bu scriptle birlikte SQL Server ortamınızda:

  • Her gece belirtilen saatte otomatik tam yedek alınır
  • Yedek doğrulanır, bozuk dosya tespit edilir
  • 5 günden eski yedekler otomatik temizlenir
  • Hata durumunda Job fail olarak işaretlenir ve izleme sistemleri uyarılabilir
  • Tüm işlemler log dosyasına kaydedilir

Yedekleme sürecinizi tamamen otomatize etmek için bu scripti kendi ortamınıza uyarlayarak kullanabilirsiniz.

💡BONUS BİLGİ

SQL Server’da Disk Partition Ayrımı Neden Yapılır?

SQL Server farklı türde I/O işlemleri yapar. Her dosya türünün okuma/yazma karakteri farklıdır. Bunları aynı diske koyarsan birbirlerinin performansını olumsuz etkiler.
Neden Ayırıyoruz?

1. Performans Log dosyası sıralı yazma yapar, data dosyası rastgele okuma yapar. Aynı diskte yarışırsa ikisi de yavaşlar. Ayrı disklerde paralel çalışır.

Özet

Tek diskte her şey çalışır ama birbirini ezer. Ayrı disklerde her dosya kendi hızında, birbirini beklemeden çalışır.

Özellikle TempDB ve Log dosyalarını ayırmak en kritik adımdır. Yüksek trafikli sistemlerde bu ayrım performansa doğrudan yansır.

Bir yanıt yazın