MariaDB için Otomatik Yedekleme: mysqldump, Rotasyon ve Geri Yükleme Testi
Her gece çalışan, eski yedekleri temizleyen ve asıl önemlisi geri yüklenebildiği doğrulanan bir MariaDB yedekleme düzeni nasıl kurulur? Betik, systemd timer ve test yöntemi.
Yedekleme konusundaki en pahalı ders şudur: yedeği olan değil, geri yükleyebilen kişi güvendedir. Birçok kurulumda yedek dosyası düzenli olarak oluşur ama bozuktur, boştur veya eksik veri içerir. Fark edilmesi için bir felaket gerekir. Bu yazıda MariaDB için basit ama sağlam bir düzen kuracağız.
Mantıksal yedek nedir?
mysqldump (MariaDB'de mariadb-dump ismiyle de bulunur) veritabanını, yeniden oluşturan SQL komutları olarak dışa aktarır. Küçük ve orta ölçekli veritabanları (birkaç GB'a kadar) için en pratik yöntemdir. Çıktı bir metin dosyasıdır; sıkıştırılır, başka makineye kopyalanır, sürümler arası taşınabilir.
Çok büyük veritabanlarında veya saniye bazında kurtarma gerektiğinde fiziksel yedek (mariabackup) ve binlog tabanlı noktaya geri dönüş gerekir. Bu yazının kapsamı dışındadır.
1. Yedek için ayrı, kısıtlı bir kullanıcı
Yedeği root ile almak gereksiz risktir. Yalnızca okuma yetkisi olan bir kullanıcı oluşturun:
CREATE USER 'yedek'@'localhost' IDENTIFIED BY 'guclu-bir-parola';
GRANT SELECT, SHOW VIEW, TRIGGER, LOCK TABLES, EVENT ON uygulama_db.* TO 'yedek'@'localhost';
FLUSH PRIVILEGES;
Parolayı komut satırına yazmak yerine ~/.my.cnf içinde tutun ve izni kısıtlayın:
[client]
user=yedek
password=guclu-bir-parola
chmod 600 ~/.my.cnf
Komut satırına yazılan parola ps çıktısında diğer kullanıcılara görünür; bu dosya yöntemi bunu engeller.
2. Yedekleme betiği
/usr/local/bin/db-yedek.sh:
#!/usr/bin/env bash
set -euo pipefail
DB="uygulama_db"
DIZIN="$HOME/yedekler"
TARIH="$(date +%Y%m%d_%H%M%S)"
DOSYA="$DIZIN/${DB}_${TARIH}.sql.gz"
SAKLA_GUN=14
mkdir -p "$DIZIN"
# --single-transaction: InnoDB tablolarını kilitlemeden tutarlı kopya alır
mariadb-dump --single-transaction --routines --events "$DB" | gzip -9 > "$DOSYA.gecici"
# Dosya sıkıştırma açısından sağlam mı?
gzip -t "$DOSYA.gecici"
mv "$DOSYA.gecici" "$DOSYA"
# Eski yedekleri sil
find "$DIZIN" -name "${DB}_*.sql.gz" -mtime +"$SAKLA_GUN" -delete
echo "TAMAM: $DOSYA ($(du -h "$DOSYA" | cut -f1))"
Dikkat edilecek noktalar:
set -euo pipefailsayesinde herhangi bir adım hata verirse betik durur.pipefailolmadanmariadb-dumpçökse bilegzipbaşarılı döner ve boş bir yedek "başarılı" görünür.- Dosya önce
.geciciadıyla yazılır, test edilir, sonra asıl adına taşınır. Yarım kalmış bir dosya yedek gibi görünmez. --single-transactionyalnızca InnoDB tablolarında tutarlılık sağlar. MyISAM tabloları varsa kilitleme gerekir.
sudo chmod +x /usr/local/bin/db-yedek.sh
3. systemd timer ile zamanlama
/etc/systemd/system/db-yedek.service:
[Unit]
Description=Veritabani yedegi
[Service]
Type=oneshot
User=pi
ExecStart=/usr/local/bin/db-yedek.sh
/etc/systemd/system/db-yedek.timer:
[Unit]
Description=Her gece veritabani yedegi
[Timer]
OnCalendar=*-*-* 03:15:00
Persistent=true
RandomizedDelaySec=120
[Install]
WantedBy=timers.target
Persistent=true, cihaz o saatte kapalıysa açıldığında kaçırılan çalıştırmayı telafi eder. Cron'da bu yoktur. Etkinleştirin:
sudo systemctl daemon-reload
sudo systemctl enable --now db-yedek.timer
systemctl list-timers db-yedek.timer
İlk denemeyi beklemeden sudo systemctl start db-yedek.service ile yapın ve journalctl -u db-yedek ile sonucu görün.
4. Yedeği başka yere kopyalayın
Yedek, veritabanıyla aynı diskte duruyorsa disk bozulduğunda ikisi birlikte gider. En az bir kopyayı başka bir cihaza taşıyın. rsync ile SSH üzerinden:
rsync -a --delete-after "$HOME/yedekler/" kullanici@baska-makine:/yedekler/uygulama/
Bu konunun mantığı 3-2-1 yedekleme kuralı yazımızda anlatılıyor.
5. Geri yükleme testi: asıl önemli adım
Ayda bir, yedeği ayrı bir test veritabanına yükleyip kayıt sayısına bakın:
mariadb -e "CREATE DATABASE IF NOT EXISTS test_geri_yukle"
gunzip -c ~/yedekler/uygulama_db_20261004_031500.sql.gz | mariadb test_geri_yukle
mariadb -e "SELECT COUNT(*) FROM test_geri_yukle.hareket"
mariadb -e "DROP DATABASE test_geri_yukle"
Sayı üretimdeki tabloyla (yedek saatine göre) tutarlıysa yedeğiniz gerçektir. Bu testi takvime yazın; "yaparım" demek yetmez.
Kontrol listesi
- Yedek kullanıcısı yalnızca gerekli yetkilere sahip.
- Parola
~/.my.cnfiçinde ve izni 600. pipefailaçık, geçici dosya adı kullanılıyor.- Timer
Persistent=true. - Bir kopya başka cihazda.
- Geri yükleme testi takvimde.
- Yedekte kişisel veri varsa saklama süresi ve erişim yetkisi belirlenmiş (bkz. KVKK yazımız).