ZFS’in en büyük özelliklerinden bir tanesi “bedavadan az pahalı” snapshot’lar. Bunlarla çok büyük yedekleme olanakları doğuyor. Ayrıca ZFS -Sun tarafından geliştirilmiş bir dosya sistemi olarak- yedeklerinizi aynı makinada almanın anlamsızlığını da hatırlatıp zfs send ve zfs receive komutlarını sunuyor.
ZFS Snapshot’ları
Snapshot burada bir dosya sisteminin o anki görüntüsü demek. Tam anlamıyla fotoğrafını çekiyorsunuz. Yedekleme açısından, siz yedeklerinizi kopyaladığınız sırada bunların değişmeyeceğini garanti altına alıyor. Özellikle canlı (kullanımdaki) bir sistemde yedeklerin kopyalanması sırasında dosya sisteminde başka kaynaktan değişiklik olması felaket anlamına gelebilir.
Bir başka kullanımı dosya sistemlerini (bir yere kopyalamasanız bile) belirli periyodlarla yedeklemek. Bu şekilde isterseniz Apple’ın Time Machine’i gibi son günün her saat başı, son haftanın her günü, son ayın her haftası şeklinde yedekler tutup “bana geçen Cumartesi günkü halini göster” diyebilirsiniz.
Bir de klonlama var. Bir ZFS dosya sisteminin snapshot’ını alıp başka bir yere klonlayabilirsiniz. Bunu sanallaştırmada veya test amaçlarıyla da kullanabilirsiniz.
ZFS’te snapshot’lar hemen hemen bedava demiştim. ZFS’in teknik yapısı nedeniyle (meraklısına, bir COW dosya sistemi olmasından dolayı) bu snapshot’lar anında alınır ve ekstra yer kaplamazlar. Snapshot aldığınız andan sonra eklediğiniz veri kadar yer kaplamaya devam edersiniz. Şöyle:
- Pazartesi sabah 100GB veriye sahip bir dataset’in snapshot’ını aldınız diyelim. Dosya sisteminiz ve snapshot’ın kapladığı alanın toplamı 100GB.
- Pazartesi gün boyunca 5GB daha veri eklediniz. Toplam kapladığınız alan 105GB
- Salı sabah bir daha snapshot aldınız. Toplam alanınız 105GB hala. Bugün 10GB daha eklediniz ve 115GB oldu.
- Çarşamba, Perşembe ve Cuma günleri de günde ortalama 10GB veri ekleyip, her sabah snapshot’ını aldınız
- Cuma akşamı itibariyle, haftanın ilk snapshot’ından son snapshot’ına kadar istediğiniz ana geri dönebilirsiniz, hepsi tutulmuş olur. Ama bu 5 yedeğin kapladığı toplam alan 145GB’dır.
- Eğer bunları her gün yedeği elle kopyalayarak yapsaydınız toplam alanınız 545GB olacaktı.
Bir ZFS bölümünün snapshot’ını almak için “@” simgesini kullanıyorsunuz. Yedeklemek istediğiniz dataset’in adını yazın, sonuna @ işareti koyun, ve snapshot’ınızı tanımlayan ismi girin.
zfs snapshot tank/home@pazartesigunu
Bu “pazartesigunu”, sizin snapshot’ınızın tanımı. Ben günün tarih ve saatini, yıldan başlayıp bitişik halde vermeyi tercih ediyorum. Bu cümleyi yazdığımda snapshot almış olsaydım 201808051113 yazacaktım; 05.08.2018 saat 11:13. Elle yazmıyorum zaten Linux’ta date komutuyla hallediyorum.
Peki ne kadar sürüyor bu snapshot alma işi? 110GB’dan fazla verinin olduğu bir dataset’in, daha doğrusu havuzun kök datasetinin snapshot’ını alalım.
…sonra da hızımı alamayıp tüm dataset’lerimi snapshot’ladım. Videoda herhangi bir hızlandırma yok. Gerçekten bu hızda snapshot alınıyor. Şimdi bu komutu (azıcık modifiye ederek) zamanlanmış görevlerinize ekleyin (crontab ile). Otomatik yedekleme sisteminiz hayırlı olsun.
Snapshot’ları tıpkı dataset’leri sildiğiniz gibi yokediyorsunuz; zfs destroy <snapshot adı> ile. Önceki komut örneğindeki snapshot’ı yoketmek için:
zfs destroy tank/home@pazartesigunu
Peki bir snapshot’a dönmek istediğinizde ne yapacaksınız? Önce snapshot’larınızın bir listesini alın:
zfs list -t snapshot
Bunda tüm havuzun snapshot’ları gelir. Belirli bir dataset’in snapshot’larını listelemek için -r anahtarını da kullanın.
zfs list -r -t snapshot tank/home
Şimdi bir önceki snapshot’a dönmeye hazırsınız:
zfs rollback tank/home@pazartesigunu
Tıpkı bir zaman makinası gibi, verinizin pazartesi günkü haline döndünüz.
Bu dönüş işleminin kısıtlamaları var. Sadece son snapshot’a dönebilirsiniz. Yani daha eskisine dönmek için aradaki diğer snapshot’ları silmeniz gerekir. Bu size tuhaf geliyorsa Geleceğe Dönüş serisini hatırlayın. Zamanda geçmişe gitmek, zaman çizgisinde bir kırılma ve alternatif bir zaman çizgisi yaratıyordu. 🙂 Mantıklı yani böyle olması. Bunun dışında, doğal olarak bir snapshot’ı düzenleyemiyorsunuz. Snapshot’lar aslında aldığınız dataset’in alt datasetleri muamelesi gördüğünden de snapshot’ları da silmeden o dataset’i silemiyorsunuz.
ZFS Klonlama
Klonlama önceki paragraftaki duruma bir çözüm getiriyor. Herhangi bir snapshot’ı “klonlayarak” ayrı bir dosya sistemi niyetine kullanabiliyorsunuz. Klonladıktan sonra buna dosya ekleme-çıkarma da serbest.
zfs clone tank/home@pazartesigunu tank/pazartesihome
home dataset’inizin pazartesi günkü hali artık tank/pazartesihome adıyla kullanımınıza hazır. Bunu yapma amacınız sadece o snapshot’a yazma erişimi elde etmek değil. Aslında klonların daha çok işinize yarayacak amacı hızlıca test sistemleri oluşturmak veya canlı bir sistemin o anki halini bir test sisteminde yeniden yaratmak. Böylece test sisteminiz ile canlı sisteminiz arasındaki farklardan kaynaklanan yazılım hatalarına karşı da hızlı bir önlem almanıza yardım ediyor.
Klonlar, snapshot’ların aksine, normal dataset muamelesi görüyor. Buna kapladığı alan da dahil; bir işletim sisteminin klonunu alabilirsiniz ve o klonu açıp içine bir şeyler eklemediğiniz sürece ek alan kaplamaz. Klondaki tek şartınız bu klonun kökü olan snapshot’ı silemiyor olmanız.
ZFS gönderme ve alma (send ve receive)
Yedekleri, yedeğini aldığınız makinada tutmanın bir anlamı yok. Bunları bir yere kopyalamak gerek. Burada zfs send ve zfs receive komutları devreye giriyor.
zfs send komutu ile havuzunuzdaki her şeyi (beraber veya ayrı ayrı) başka bir yerlere gönderebilirsiniz. Yerlere sözünü kalın, vurgulu yazmamın sebebi komutun esnekliğini ifade etmekti.
Bu esnekliğin nedeni ZFS’in send komutuyla gayet sıradan bir veri akışı yaratıyor olması. Bunun hedefi her yer olabilir, isterseniz bir dosyaya kaydedebilirsiniz, isterseniz başka bir komuta girdi olarak verebilirsiniz, isterseniz de birazdan göreceğiniz zfs receive komutuyla ortak kullanırsınız.
zfs send komutunu kullanmadan önce bir snapshot almanız gerekiyor -canlı bir dataset’i send’le gönderemezsiniz ve zaten böyle bir şey yapmanın anlamı yok. Bizim emektar zfstester sisteminde bir dataset’in yedeğini alıp bir yerlere gönderelim.
zfs snapshot tank/home@evyedegi
zfs send tank/home@evyedegi > /yedek/evyedek.img
Bu evyedek.img dosyası herhangi bir dosya sisteminin imajıyla aynı şey. Hani “imaj alma programı”yla Windows diskinin görüntüsünü alıyorsunuz ya. Onu sistemi kapatmadan yaptığınızı düşünün.
E bu sıradan bir veri akışıysa biz bunu sıkıştırırız da?
Sıkıştırılmış dosyanın orijinalden büyük olduğunu sonradan farkettim, sebebi o alanın zaten zor sıkıştırılan bir yapıda olması. Her dosya sıkışmaz. 🙂 Gerçek hayatta böyle olmayacak.
Neyse. Bu evyedek dosyasını koyduğumuz yer kendi diskimiz, sistemdeki başka bir disk, USB ile bağlanmış bir depolama, ağ üzerinde başka bir makinadaki Windows paylaşımı… Her yer olur.
zfs receive komutu send’in tam tersidir; herhangi bir akışı alıp bunu ZFS havuzumuzda bir dataset olarak oluşturur. İlk zfs send örneğindeki imaj dosyasını ZFS havuzumuza şöyle dahil edebilirdik:
zfs receive tank/uzaktangelen < /yedek/evyedek.img
Bu iki komutu birleştirmek ise ZFS’i düzenli yedek alacağınız, sağlam bir veri merkezinde yarı-tanrı pozisyonuna sokuyor.
zfs send home@evyedegi | ssh root@192.168.122.1 “zfs receive trantortank/zfstesterevyedegi”
Aşağıda kaynak makinamızda bu komutu çalıştırıyoruz.
Şu da karşı taraftaki makinada (trantor’da) bulunan ZFS havuzu.
Bu komutun basitliği ile veri merkezinizden fiziksel olarak ayrı bir lokasyona düzenli yedek almak çok kolay hale geliyor. Daha önce bahsettiğim gibi, sistemlerinizde günlük düzenli snapshot’ları alan bir betik (script) yazın. Sonra bu komutu (SSH sertifika girişi gibi mevzularla) biraz düzenleyip ikisini de zamanlanmış görevlere alın. Sisteminiz düzenli olarak yedeklerini alsın ve geceyarılarında uzak lokasyondaki güvenli yedek biriminize aktarsın. Hatta ağdan gönderdiğiniz için arada sıkıştırın ve şifreleyin. Hepi topu iki satır komutta.