dd Komutu ile Disk Klonlama Rehberi
Disk klonlama denince aklıma hep o ilk panic anı gelir: production sunucu çökmüş, yedek yok, müşteri arıyor. O günden sonra dd komutunu öğrenmek benim için bir tercih değil, zorunluluk haline geldi. Bugün size Linux dünyasının en güçlü ve en tehlikeli araçlarından birini anlatacağım. “Dangerous Destroyer” ya da resmi adıyla “data duplicator” olan dd, doğru kullanıldığında hayat kurtarır, yanlış kullanıldığında ise veriyi yok eder.
dd Nedir ve Neden Bu Kadar Önemlidir?
dd, Unix/Linux dünyasında onlarca yıldır var olan, blok bazında veri kopyalama yapan bir komut satırı aracıdır. Dosya sistemi seviyesinde değil, doğrudan ham disk bloklarıyla çalışır. Bu ne demek? Bir dosyayı kopyaladığınızda işletim sistemi dosya sistemini anlar ve dosyaları okur. dd ise bunların hiçbirini umursamaz; diski veya bölümü bir byte akışı olarak görür ve olduğu gibi kopyalar. Boş alanlar, silinmiş dosyalar, partition table, bootloader, her şey dahil.
Bu özellik dd’yi hem çok güçlü hem de çok tehlikeli yapıyor. Yanlış hedef belirtirseniz, birkaç saniye içinde diskinizin tüm içeriği gidebilir. Komut satırında of= parametresine yanlış bir şey yazarsanız geri dönüşü yoktur. Bu yüzden her dd komutunu çalıştırmadan önce iki kez kontrol etmeyi alışkanlık haline getirmenizi şiddetle tavsiye ederim.
Temel Sözdizimi ve Parametreler
dd komutunun temel yapısı şu şekildedir:
dd if=<kaynak> of=<hedef> [seçenekler]
Sık kullandığım parametreler şunlar:
- if: Input file, kaynak dosya veya cihaz
- of: Output file, hedef dosya veya cihaz
- bs: Block size, her seferinde okunup yazılacak blok boyutu (512, 1M, 4M gibi)
- count: Kaç blok kopyalanacağı
- skip: Kaynakta atlanacak başlangıç blok sayısı
- seek: Hedefte atlanacak başlangıç blok sayısı
- status=progress: Kopyalama ilerlemesini canlı gösterir (modern dd versiyonlarında)
- conv=noerror: Okuma hatalarında devam et
- conv=sync: Hatalı blokları sıfırlarla doldur
- conv=fsync: Yazma tamamlandıktan sonra disk cache’ini temizle
- iflag=direct: Kaynak için doğrudan I/O kullan, önbellek bypass
- oflag=direct: Hedef için doğrudan I/O kullan
Şimdi bunları nasıl kullandığımızı gerçek senaryolarla görelim.
Senaryo 1: Tam Disk Klonlama
En temel ve en çok ihtiyaç duyduğunuz senaryo budur. Bir sunucunun diskini birebir kopyalamak istiyorsunuz. Örneğin eski bir SATA disk var, yeni bir SSD aldınız ve geçiş yapmak istiyorsunuz.
Önce hangi diskin ne olduğunu netleştirelim:
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,MODEL
fdisk -l
Disklerinizi tanımladıktan sonra klonlama işlemine geçebilirsiniz. Burada kritik nokta şu: hedef disk kaynak disk ile aynı boyutta veya daha büyük olmalı.
dd if=/dev/sda of=/dev/sdb bs=4M status=progress conv=fsync
Bu komut /dev/sda diskini /dev/sdb‘ye blok blok kopyalar. bs=4M parametresi blok boyutunu 4 megabyte yaparak işlemi hızlandırır. Varsayılan 512 byte’lık blok boyutuyla kopyalama yaparsanız aynı işlem 10 kat daha uzun sürebilir. status=progress ise kopyalamanın nerede olduğunu görmemizi sağlar, yoksa komut çalışır ama ekranda hiçbir şey göremezsiniz ve ne zaman biteceğini bilemezsiniz.
Disk kopyalama tamamlandıktan sonra mutlaka doğrulama yapın:
md5sum /dev/sda
md5sum /dev/sdb
Her iki hash değeri eşleşiyorsa klonlama başarıyla tamamlanmış demektir.
Senaryo 2: Disk Image Oluşturma
Fiziksel bir diski başka bir fiziksel diske kopyalamak yerine, diski bir image dosyası olarak kaydetmek çok daha pratik ve yaygın bir yöntemdir. Bu şekilde image dosyasını farklı bir konuma yedekleyebilir, daha sonra istediğiniz zaman geri yükleyebilirsiniz.
dd if=/dev/sda of=/backup/server-disk-$(date +%Y%m%d).img bs=4M status=progress
Tarih eklemek iyi bir alışkanlık. Yarın geri dönüp hangi image’ın ne zaman alındığını anlamak için zaman damgası çok işe yarıyor.
Büyük disklerle çalışıyorsanız ve depolama alanınız kısıtlıysa, image’ı sıkıştırarak kaydedebilirsiniz:
dd if=/dev/sda bs=4M status=progress | gzip -9 > /backup/server-disk-$(date +%Y%m%d).img.gz
Pipe kullanarak dd çıktısını doğrudan gzip’e yönlendiriyoruz. -9 maksimum sıkıştırma demek, biraz daha yavaş ama çok daha küçük dosya elde ediyorsunuz. Hız ile boyut arasında denge kurmak istiyorsanız -6 veya -4 kullanabilirsiniz.
Ağ üzerinden başka bir sunucuya kopyalama yapıyorsanız SSH ile birleştirebilirsiniz:
dd if=/dev/sda bs=4M status=progress | gzip -c | ssh kullanici@yedek-sunucu "gunzip -c > /backup/server-disk.img"
Senaryo 3: Image’dan Disk Geri Yükleme
Felaket kurtarma senaryosunun tam olarak bu noktasında her şey kritik hale gelir. Sistem çöktü, yeni disk takıldı, image’ı geri yüklemek gerekiyor.
Normal image için:
dd if=/backup/server-disk-20240115.img of=/dev/sda bs=4M status=progress conv=fsync
Sıkıştırılmış image için:
gunzip -c /backup/server-disk-20240115.img.gz | dd of=/dev/sda bs=4M status=progress conv=fsync
Burada çok önemli bir uyarı: geri yükleme yapacağınız disk sisteme bağlı ve mount edilmiş olmamalı. Bunun için genellikle bir live CD/USB’den boot etmek gerekir. SystemRescue, Ubuntu Live veya benzeri bir ortamdan çalışarak bu işlemi yapmanızı öneririm.
Geri yükleme tamamlandıktan sonra partition table’ın doğru okunduğunu kontrol edin:
partprobe /dev/sda
lsblk /dev/sda
Eğer hedef disk kaynak diskten büyükse, arta kalan alanı kullanabilmek için partition’ı genişletmeniz gerekecek. Bunun için parted veya gparted kullanabilirsiniz.
Senaryo 4: Sadece Partition Kopyalama
Bazen tüm diski değil, sadece belirli bir partition’ı kopyalamak isteriz. Bu hem daha hızlı hem de daha az alan kaplar.
dd if=/dev/sda1 of=/backup/boot-partition-$(date +%Y%m%d).img bs=4M status=progress
Veya bir partition’dan diğerine kopyalama:
dd if=/dev/sda1 of=/dev/sdb1 bs=4M status=progress conv=fsync
Burada dikkat edilmesi gereken nokta, hedef partition’ın en az kaynak kadar büyük olması gerektiğidir. Ayrıca partition kopyaladıktan sonra dosya sistemini kontrol etmek iyi bir pratiktir:
fsck -n /dev/sdb1
-n parametresi sadece kontrol eder, hiçbir şeyi onarmaz veya değiştirmez.
Senaryo 5: MBR ve Bootloader Yedekleme
Sistem bir türlü boot olmuyorsa ve MBR bozulduysa, daha önce yedeğini aldıysanız geri yükleme işi dakikalar alır. MBR, diskin ilk 512 byte’ında bulunur.
MBR yedeklemek için:
dd if=/dev/sda of=/backup/mbr-backup-$(date +%Y%m%d).bin bs=512 count=1
Sadece MBR kopyalamak ve partition table’a dokunmamak için (ilk 446 byte):
dd if=/dev/sda of=/backup/mbr-only-$(date +%Y%m%d).bin bs=446 count=1
MBR geri yüklemek için:
dd if=/backup/mbr-backup-20240115.bin of=/dev/sda bs=512 count=1
GPT disklerle çalışıyorsanız MBR kavramı biraz farklıdır. GPT başlık bilgisi diskin ilk ve son sektörlerinde bulunur. Güvenli bir yedekleme için tüm GPT yapısını yedeklemek daha doğru olur:
sgdisk --backup=/backup/gpt-backup-$(date +%Y%m%d).bin /dev/sda
İlerleme Takibi ve Zaman Yönetimi
Büyük disklerde dd komutunun ne kadar süreceğini bilmek önemlidir. status=progress var ama eski sistemlerde bu parametre desteklenmeyebilir. Bu durumda başka bir terminal açarak dd process’ine sinyal gönderebilirsiniz:
# Başka bir terminal veya screen session'ında
watch -n 5 'kill -USR1 $(pgrep dd)'
Veya PID’i öğrenip manuel olarak:
kill -USR1 $(pgrep dd)
Her sinyal gönderdiğinizde dd mevcut istatistiklerini stdout’a basar: kaç byte kopyalandı, kaç saniye geçti, ortalama hız nedir.
Daha modern bir yaklaşım olarak pv (pipe viewer) komutunu dd ile birlikte kullanmak mükemmel bir çözümdür:
dd if=/dev/sda bs=4M | pv -s $(blockdev --getsize64 /dev/sda) | dd of=/dev/sdb bs=4M
Bu komut ilerleme çubuğu, hız, tahmini bitiş süresi gibi bilgileri güzel bir şekilde gösterir. pv kurulu değilse apt install pv veya yum install pv ile yükleyebilirsiniz.
Hatalı Disklerden Veri Kurtarma
Bu konu gerçekten önemli. Disk bozulmaya başladığında panik yapmak yerine hızlıca veri kurtarma operasyonu başlatmak gerekir. dd bu noktada da işe yarıyor.
Okuma hatası veren bir diskten mümkün olduğunca fazla veri kurtarmak için:
dd if=/dev/sda of=/backup/damaged-disk.img bs=512 conv=noerror,sync status=progress
conv=noerror okuma hatası olduğunda durmak yerine devam et demek. conv=sync ise hatalı blokları sıfırlarla (null byte) doldurur, böylece image dosyasının boyutu tutarlı kalır ve dosya sistemi offsetleri bozulmaz.
Daha akıllıca bir yaklaşım için ddrescue komutunu kullanmanızı öneririm. Bu araç önce hatasız alanları kopyalar, sonra hatalı alanlara geri döner ve tekrar tekrar dener:
ddrescue -d -r3 /dev/sda /backup/damaged-disk.img /backup/rescue.log
-d direct mode demek, -r3 hatalı alanları 3 kez daha denesek demek. Log dosyası kurtarma işleminin neresinde olduğunu kaydeder, işlem yarıda kesilirse kaldığı yerden devam edebilirsiniz.
Performans Optimizasyonu
dd ile büyük diskler kopyalarken performans kritik önem taşır. İşte pratik ipuçları:
Blok boyutunu optimize edin. Genellikle 4M ile 64M arası değerler en iyi performansı verir:
dd if=/dev/sda of=/dev/sdb bs=64M status=progress conv=fsync
Doğrudan I/O kullanarak kernel buffer cache’ini bypass edin. Bu bazen hızı artırır, bazen azaltır; test etmek gerekir:
dd if=/dev/sda of=/dev/sdb bs=4M iflag=direct oflag=direct status=progress
Çok sayıda CPU çekirdeği varsa paralel sıkıştırma kullanabilirsiniz:
dd if=/dev/sda bs=4M status=progress | pigz -9 > /backup/server-disk.img.gz
pigz parallel gzip demek, çok çekirdekli sistemlerde gzip’ten çok daha hızlı çalışır. apt install pigz ile kurabilirsiniz.
Güvenlik ve Güvenli Silme
dd’nin bir diğer önemli kullanım alanı güvenli disk silmedir. Bir sunucuyu elden çıkarmadan önce diskteki verilerin kurtarılamamasını istiyorsanız:
dd if=/dev/urandom of=/dev/sda bs=4M status=progress
Bu komut tüm diski rastgele verilerle doldurur. Gerçekten güvenli bir silme için bu işlemi 3 kez tekrarlamanız önerilir (DoD standartı). Ancak modern SSD’lerde bu yöntem 100% etkili olmayabilir; SSD’ler için üreticinin güvenli silme araçlarını kullanmak daha doğrudur.
Test ortamı veya geliştirme için diski sıfırlarla doldurmak yeterliyse:
dd if=/dev/zero of=/dev/sda bs=4M status=progress
Otomasyon ve Cronjob ile Periyodik Snapshot
Production ortamında bu işlemleri manuel yapmak sürdürülebilir değil. Basit bir script ile bu işlemi otomatize edebilirsiniz.
#!/bin/bash
KAYNAK="/dev/sda"
HEDEF_DIZIN="/backup/snapshots"
TARIH=$(date +%Y%m%d_%H%M%S)
SUNUCU=$(hostname -s)
LOG="/var/log/disk-backup.log"
echo "$(date): Backup basliyor - $SUNUCU" >> $LOG
dd if=$KAYNAK bs=4M status=progress 2>>$LOG |
gzip -6 > $HEDEF_DIZIN/${SUNUCU}-${TARIH}.img.gz
if [ $? -eq 0 ]; then
echo "$(date): Backup basarili - $HEDEF_DIZIN/${SUNUCU}-${TARIH}.img.gz" >> $LOG
# 30 gunden eski yedekleri temizle
find $HEDEF_DIZIN -name "*.img.gz" -mtime +30 -delete
echo "$(date): Eski yedekler temizlendi" >> $LOG
else
echo "$(date): HATA - Backup basarisiz!" >> $LOG
# Bildirim gonder
echo "Disk backup basarisiz: $SUNUCU" | mail -s "BACKUP HATASI" [email protected]
fi
Bu scripti crontab’a ekleyerek otomatik çalıştırabilirsiniz:
# Her gece saat 02:00'da calistir
0 2 * * * /usr/local/bin/disk-backup.sh
Sık Yapılan Hatalar ve Dikkat Edilmesi Gerekenler
Deneyimlerimden derlediğim en kritik hatalar şunlar:
- if ve of parametrelerini karıştırmak: Bu en büyük felakettir.
if=/dev/sdb of=/dev/sdayerineif=/dev/sda of=/dev/sdbyazmak isteyip yanlış yazarsanız, kaynak diskinizi hedef ile ezip geçersiniz. Her zaman iki kez kontrol edin.
- Mount edilmiş diski kopyalamak: Aktif olarak kullanılan bir diski kopyalamak tutarsız bir image üretir. Mümkünse sistem kapalıyken veya live ortamdan kopyalama yapın.
- Hedef boyutunu kontrol etmemek: Kaynak disk 500GB, hedef 250GB olursa dd bir süre sonra hata verir ve yarım image kalır.
- bs değerini çok küçük bırakmak: Varsayılan 512 byte değeriyle 1TB disk kopyalamak saatler sürebilir. Mutlaka bs parametresini ayarlayın.
- Kopyalama sonrası doğrulama yapmamak: Hash kontrolü yapmadan yedeğin geçerli olduğunu varsaymak risklidir.
Alternatif Araçlar ile Karşılaştırma
dd güçlü ama her zaman en iyi seçenek olmayabilir. Duruma göre alternatifler düşünülmeli:
- Clonezilla: Grafiksel arayüzü olan, dosya sistemi farkında kopyalama yapan bir araç. Boş alanları kopyalamaz, bu yüzden dd’den daha hızlıdır.
- rsync: Dosya bazında, değişiklikleri takip eden yedekleme. Disk klonu değil ama çoğu durumda yeterli.
- LVM snapshot: Aktif sistemi dondurmadan anlık görüntü almak için ideal.
- Veeam / Backup Exec: Enterprise ortamlar için, özellikle sanal makinelerde.
dd’nin avantajı; kurulum gerektirmeyen, her Linux sistemde hazır olan, scriptlenebilen ve ham disk seviyesinde çalışan yapısıdır.
Sonuç
dd komutunu öğrenmek, bir sistem yöneticisi olarak temel yeteneklerinizden biri olmalı. Ham ve acımasız bir araç, ama doğru kullanıldığında en güvenilir yedekleme ve kopyalama yöntemlerinden birini sunar. Yıllarca üretim ortamında kullandım ve hiç elimi yaktırmadı; ama dikkatli olduğum için yaktırmadı.
Pratik önerim şu: Bu komutları önce bir sanal makinede veya test ortamında deneyin. if ve of parametrelerine her zaman ihtiyaçtan bir saniye fazla bakın. İşlem öncesi lsblk ve fdisk -l ile disk düzeninizi doğrulayın. Yedeklerinizin doğruluğunu hash ile kontrol edin. Ve en önemlisi, aldığınız yedekleri periyodik olarak geri yükleme testine tabi tutun; yoksa yedek aldığınızı sanırsınız ama gerçekte bozuk bir image biriktirir durursunuz.
Disk klonlama ve yedekleme konusunda sorularınız varsa yorumlara yazın, elimden geldiğince yanıtlamaya çalışırım.
