Laravel İle Dinamik Veritabanı Yedekleme Sistemi Nasıl Yapılır?

Laravel İle Dinamik Veritabanı Yedekleme Sistemi Nasıl Yapılır?
Laravel İle Dinamik Veritabanı Yedekleme Sistemi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Sistemi kurmadan önce sunucunuzda ve Laravel projenizde belirli araçların yüklü olması gerekir. Özellikle veritabanı dump (döküm) işlemleri için sisteminizde ilgili veritabanı istemcisinin bulunması şarttır.

  • PHP Sürümü: 8.2 veya üzeri.
  • Laravel Sürümü: 10.x veya 11.x.
  • Veritabanı İstemcisi: MySQL kullanıyorsanız mysqldump, PostgreSQL kullanıyorsanız pg_dump komutlarının terminalden erişilebilir olması gerekir.
  • Depolama: Yedeklerin kaydedileceği yerel bir disk veya AWS S3 gibi bir bulut depolama servisi.

Sunucunuzda mysqldump komutunun çalışıp çalışmadığını kontrol etmek için terminalde şu komutu çalıştırabilirsiniz:

mysqldump --version

Eğer "komut bulunamadı" hatası alırsanız, veritabanı istemcilerini sunucunuza (örneğin Ubuntu üzerinde sudo apt install mysql-client ile) kurmanız gerekmektedir.

Adım 1: Yedekleme İçin Laravel Konsol Komutu Oluşturma

Laravel'de yedekleme işlemini bir "Artisan" komutu olarak tanımlamak, işlemin hem manuel olarak tetiklenebilmesini hem de zamanlanmış görevlere kolayca entegre edilmesini sağlar. Öncelikle yeni bir komut sınıfı oluşturalım.

php artisan make:command DatabaseBackupCommand

Bu komut, app/Console/Commands dizininde bir dosya oluşturacaktır. Şimdi bu dosyayı düzenleyerek yedekleme mantığını içerisine yerleştirelim.

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;

class DatabaseBackupCommand extends Command
{
    protected $signature = 'db:backup';
    protected $description = 'Veritabanını yedekler ve storage dizinine kaydeder.';

    public function handle()
    {
        $filename = "backup-" . date('Y-m-d_H-i-s') . ".sql";
        $path = storage_path("app/backups/" . $filename);

        $command = sprintf(
            'mysqldump -u%s -p%s %s > %s',
            config('database.connections.mysql.username'),
            config('database.connections.mysql.password'),
            config('database.connections.mysql.database'),
            $path
        );

        exec($command);
        $this->info("Yedekleme başarıyla oluşturuldu: " . $filename);
    }
}

Bu kod bloğu, mysqldump aracını kullanarak veritabanı içeriğini bir .sql dosyasına aktarır. exec() fonksiyonu, PHP üzerinden sunucu komutlarını çalıştırmamıza olanak tanır.

Güvenlik Uyarısı: Veritabanı şifrelerini doğrudan komut satırında geçirmek güvenlik riski oluşturabilir. Üretim ortamında, şifreleri bir yapılandırma dosyasından okumak yerine, .my.cnf gibi bir kimlik doğrulama dosyası kullanmanız önerilir.

Adım 2: Yedekleme Stratejileri Karşılaştırması

Veritabanı yedekleme işlemleri için farklı yöntemler mevcuttur. İhtiyacınıza göre en uygun olanı seçmek için aşağıdaki tabloyu inceleyebilirsiniz.

Yöntem Avantajı Dezavantajı
mysqldump (Native) Hızlı, basit, standart. Büyük veritabanlarında kilitlenme yapabilir.
Laravel Paketleri Kurulumu kolay, gelişmiş özellikler. Bağımlılık (dependency) artar.
Bulut Servisleri Otomatik, yönetimi kolay. Maliyetli olabilir.

Adım 3: Zamanlanmış Görevler ile Otomasyon

Yedekleme işleminin her gün belirli bir saatte otomatik çalışması için Laravel'in Schedule özelliğini kullanacağız. routes/console.php dosyasına veya app/Console/Kernel.php (sürümünüze bağlı olarak) dosyasındaki schedule metoduna şu satırı ekleyin:

use Illuminate\Support\Facades\Schedule;

Schedule::command('db:backup')->dailyAt('03:00');

Bu yapılandırma, sistemin her gece saat 03:00'te veritabanı yedeğini otomatik olarak almasını sağlar. cron servisinizin sunucuda aktif olduğundan emin olun.

Adım 4: Yedeklerin Güvenli Depolanması ve Temizliği

Yedek dosyaları sürekli birikirse sunucuda disk alanı sorunu yaşanabilir. Belirli bir süreden eski olan yedekleri otomatik olarak silen bir mantık eklemek, sistemin sağlığı için kritiktir.

public function cleanOldBackups()
{
    $files = Storage::files('backups');
    foreach ($files as $file) {
        if (Storage::lastModified($file) < now()->subDays(7)->timestamp) {
            Storage::delete($file);
        }
    }
}

Bu metodu handle() metodunuzun sonuna ekleyerek, her yedekleme işleminden sonra 7 günden eski dosyaların temizlenmesini sağlayabilirsiniz.

Adım 5: Hata Yönetimi ve Bildirimler

Yedekleme işlemi başarısız olursa haberdar olmanız gerekir. Laravel'in Notification sistemini kullanarak hata durumunda e-posta veya Slack bildirimi alabilirsiniz.

try {
    exec($command, $output, $returnCode);
    if ($returnCode !== 0) {
        throw new Exception("Yedekleme komutu hata kodu ile sonlandı.");
    }
} catch (\Exception $e) {
    Log::error("Yedekleme hatası: " . $e->getMessage());
    // Buraya bildirim gönderen kod eklenebilir
}

Bu yapı, işlemin başarılı olup olmadığını kontrol eder ve bir hata oluşursa Laravel'in log sistemine detaylı bilgi kaydeder.

Sıkça Sorulan Sorular

Yedekleme sırasında veritabanı kilitlenir mi?

mysqldump kullanılırken --single-transaction parametresini eklemek, InnoDB tabloları için veritabanını kilitlemeden tutarlı bir yedek almanızı sağlar.

Yedek dosyalarını nasıl şifrelerim?

Yedek dosyasını oluşturduktan sonra PHP'nin openssl_encrypt fonksiyonunu kullanarak dosyayı şifreleyebilir ve ardından saklayabilirsiniz.

Yedekleri harici bir sunucuya nasıl gönderirim?

Laravel'in Storage facade'ını kullanarak Storage::disk('s3')->put(...) komutu ile yedekleri doğrudan AWS S3 veya başka bir bulut depolama alanına yükleyebilirsiniz.

Çok büyük veritabanlarında ne yapmalıyım?

Veritabanınız çok büyükse, tüm veritabanını tek seferde almak yerine "incremental" (artımlı) yedekleme yöntemlerini veya veritabanı sağlayıcınızın sunduğu snapshot özelliklerini araştırmalısınız.

Yedeği geri yüklemek için ne yapmalıyım?

Geri yükleme işlemi için mysql -u kullanıcı -p veritabanı_adı < yedek_dosyası.sql komutunu terminalde çalıştırmanız yeterlidir.

Sorumluluk Reddi: Bu rehberdeki kodlar genel bilgilendirme amaçlıdır. Yedekleme sisteminizi canlıya almadan önce mutlaka farklı bir ortamda geri yükleme (restore) testi yapın. Hatalı yedekleme, veri kaybına yol açabilir.

Yedekleme Stratejilerinde Performans Optimizasyonu

Büyük ölçekli veritabanlarında, yedekleme işlemi sırasında sistem kaynaklarının tüketilmesi uygulamanızın yavaşlamasına neden olabilir. Özellikle mysqldump komutu çalışırken veritabanı tablolarının kilitlenmesi, kullanıcı deneyimini olumsuz etkiler. Bu durumu minimize etmek için aşağıdaki stratejileri uygulayabilirsiniz.

Single-Transaction Kullanımı

InnoDB motorunu kullanan veritabanlarında, tutarlı bir yedek almak için --single-transaction parametresini kullanmak zorunludur. Bu parametre, yedekleme sırasında tablonun kilitlenmesini engeller ve veritabanının o anki durumunun bir "snapshot"ını alır.

// Laravel komutunuzda Process sınıfını şu şekilde yapılandırın:
$process = new Process([
    'mysqldump',
    '--single-transaction',
    '--quick',
    '--lock-tables=false',
    '-u', env('DB_USERNAME'),
    '-p' . env('DB_PASSWORD'),
    env('DB_DATABASE')
]);

Veritabanı Parçalama (Partitioning) ve Filtreleme

Eğer veritabanınızda çok büyük log tabloları varsa, bunları yedekleme kapsamı dışında bırakmak yedekleme süresini ve dosya boyutunu ciddi oranda düşürür. --ignore-table parametresi ile gereksiz verileri dışarıda bırakabilirsiniz.

// Belirli tabloları yedekleme dışı bırakma örneği
$process = new Process([
    'mysqldump',
    '--ignore-table=veritabani_adi.log_tablosu',
    '--ignore-table=veritabani_adi.cache_tablosu',
    // ... diğer parametreler
]);

Yedekleme Süreçlerinde Hata Ayıklama (Debugging)

Otomatize edilmiş sistemlerde yedekleme işleminin başarısız olduğunu anlamak bazen güç olabilir. Hata ayıklama sürecini iyileştirmek için Laravel'in Log facade'ini ve Process çıktısını etkin kullanmalısınız.

Detaylı Hata Günlüğü Oluşturma

Yedekleme komutunuzun başarısız olması durumunda, sadece "hata oluştu" demek yerine, STDERR çıktısını yakalayarak log dosyasına yazdırın. Bu, sorunun veritabanı bağlantısından mı yoksa disk izninden mi kaynaklandığını anlamanızı sağlar.

try {
    $process->mustRun();
} catch (ProcessFailedException $exception) {
    Log::error('Yedekleme başarısız oldu: ' . $exception->getErrorOutput());
    
    // Yöneticiye anlık bildirim gönderin
    Notification::route('mail', 'admin@site.com')
        ->notify(new BackupFailedNotification($exception->getErrorOutput()));
}

Yedekleme Bütünlüğü Testi

Yedeklemenin çalışıyor olması, verinin geri yüklenebilir olduğu anlamına gelmez. Ayda bir kez, otomatik olarak bir "Restore Testi" gerçekleştiren bir komut yazmanız önerilir. Bu komut, yedek dosyasını geçici bir veritabanına aktarmalı ve tablo sayısını kontrol etmelidir.

Kontrol Noktası Önemi
Dosya Boyutu Kontrolü 0 byte yedekleri engeller.
Geri Yükleme Testi SQL sözdizimi hatalarını yakalar.
Depolama Alanı Kontrolü Disk dolması kaynaklı hataları önler.

Sonuç

Laravel ile dinamik veritabanı yedekleme sistemi oluşturmak, uygulamanızın güvenliği için atabileceğiniz en önemli adımlardan biridir. Bu rehberde, komut oluşturma, zamanlama, temizlik ve hata yönetimi aşamalarını adım adım inceledik. Bir sonraki adım olarak, yedeklerinizi sadece yerel diskte değil, S3 veya Google Cloud Storage gibi uzak bir lokasyonda yedekleyerek "Felaket Kurtarma" (Disaster Recovery) planınızı bir üst seviyeye taşıyabilirsiniz.

Bu yazıya tepkinizi paylaşın:
Deniz Aydın

On yıllık deneyimli bir içerik editörü olarak, karmaşık süreçleri herkesin anlayabileceği basit adımlara dönüştürmeyi seviyorum. Okuyucuların hayatını kolaylaştıracak pratik çözümler üretmek temel uzmanlık alanımdır.

Yorumlar (0)

Yorum Yaz