Postgresql Backup ve Restore İşlemleri
Postgresql veritabanı üzerinde yedek alma (backup) ve yedekten geri yükleme (restore) işlemleri için birden fazla yöntem mevcuttur. Bu yöntemlerin neler olduğunu, nasıl kullanılacağını ve detaylı örneklerini bu yazımızda işleyeceğiz.
1. Yedek Alma (Backup)
Postgres, verileri yedeklemek için temelde farklı üç yaklaşım sunar. Bunlar:
- SQL dump (Logical)
- File system-level backup (Physical)
- Continuous archiving (Point In Time Recovery)
Anlatımımıza SQL dump ile başlayacağız.
1.1 SQL Dump
Postgresql’de, bir veritabanında yer alan tüm kayıtları sırayla SQL komutları halinde dosyaya döküm alabiliriz. Bu işlem ile oluşturduğunuz yedek dosyanızı restore ettiğinizde, SQL komutları veritabanınızın o anki halini (snapshot) oluşturacak şekilde döküm sırasında olduğu gibi sırayla çalıştırılır. Bu işlemde "pg_dump"
ve "pg_dumpall"
araçları kullanılır.
Bu yardımcı programların önemli bir avantajı, PostgreSQL’in daha yeni sürümlerinde veya farklı mimarilere sahip makinelerde yedeklerinizi sorunsuz ve stabil bir halde rahatlıkla geri yükleyebilmenizdir. Dosya düzeyinde yedeklemeler (File system-level backup) ve sürekli arşivleme (Continuous archiving) gibi diğer yedekleme yöntemleri, belirli bir sunucu sürümüne ve mimarisine bağlıdır.
1.1.1 pg_dump
İlk komutumuz olan pg_dump
fonksiyonu ile tek bir veritabanını global değişkenler hariç olarak yedekleyebiliriz. Temel kullanımı şu şekildedir:
pg_dump veritabanıAdı > dumpDosyaAdı
Örnek olarak kerterizDB isimli veritabanımızı yedek almak istediğimizde aşağıdaki komutu kullanabiliriz.
pg_dump kerterizDB > kerterizDB.backup
veya
pg_dump kerterizDB -f kerterizDB.backup
pg_dump ile veritabanına erişimi olan herhangi bir cihazdan yedekleme işlemleri gerçekleştirebiliriz. Fakat pg_dump
özel izinler aracılığıyla işlem yapmaz. Eğer veritabanının tamamını yedek alacaksanız tüm tabloları okumak için yetkinizin olması gerekir. Tüm tablolar üzerinde yeterince yetkiniz yoksa, aşağıdaki örnekte olduğu gibi -n schema
ya da -t table
seçeneklerini kullanarak sadece belirli tabloların yedeğini alabiliriz.
pg_dump -t loglarTablosu kerterizDB > kerterizDB.backup
Dump işleminde -h
host ve -p
port parametrelerini kullanarak yedek alınacak sunucu ve portu özelleştirebiliriz. Eğer bu parametreleri kullanmazsanız varsayılan server localhost ya da PGHOST değişkeninde ne belirtildiyse odur. Aynı şekilde, varsayılan portun değeri de PGPORT değişkeninde belirtilen değerdir. Tabi bu parametreleri kullandığınızda farklı bir sunucuya bağlanırken mevcut oturumunuzdaki kullanıcı adı yerine veritabanı üzerinde yetkili kullanıcıyı belirtmek için -U
parametresini veya PGUSER değişkenini ayarlamalıyız.
pg_dump -h 192.168.x.x -p 5432 -U postgres kerterizDB > home/kerteriz/yedek.txt
Ayrıca ek olarak kullanabileceğiniz tüm parametreler şunlardır;
-d
, database-h
, hostname-p
, Port numarası-U
, belirtilen veritabanı kullanıcısı-w
, Şifresiz işlem yapar.-a
, şemayı değil sadece veriyi alır.-b
, dump’a büyük nesneleri dahil eder.-B
, dump’a büyük nesneleri dahil etmez.-E
, belirlenmiş karakter setinde encoding işlemi yaparak dump oluşturur.-f
, çıktı dosyası ve yer alacağı dizin adı.-F c | d | t | p
, çıktı dosya formatı (custom, directory, tar, düz metin (varsayılan)).-n
, sadece belirtilen şemaları alır.-s
, sadece şema, veri dökümü yok (user yetkileri vs.)-t
, sadece belirlenmiş tabloları alır.-v
, backup alınırıken ayrıntılı modu belirtir.-V
, pg_dump sürüm bilgisini verir.-Z
0-9, Sıkıştırılmış formatlar için kullanılır. (0-9 sıkıştırma oranı)-x
, erişim haklarını engelleyerek dump alır.
Kullanım örnekleri;
# DB_NAME test, FILE_NAME.EXT = backup.dump
pg_dump DB_NAME -f FILE_NAME.EXT
# Custom sıkıştırılmış yedek.
pg_dump -Fc DB -f FILE
# Sadece belirtilen tabloyu yedekler.
pg_dump -t "TABLE_NAME"
# Sadece belirtilen tabloların haricindekileri yedekler.
pg_dump -T "TABLE_NAME"
# Sadece STRUCTURE yani DDL
pg_dump -s
# Sadece DATA yani DQL yedekler
pg_dump -a
Kısa bir özet ve ek olarak;
- Tek bir veritabanının yedeğini alır
- Yedeği sıkıştırabilir
- Sıkıştırılmış yedeği tablo bazında açma şansı verir. (Sadece sıkıştırılmış formatta ise alır)
- Clusterdaki tüm veritabanlarında ortak olan global nesneleri yedeklemez (roller ve tablespace gibi)
- pg_dump tarafından alınan dump dosyaları tamamen tutarlıdır, çünkü dump, veritabanınızın ve pg_dump’ın çalışmaya başladığı andaki verilerinin anlık görüntüsüdür(snapshot).
- pg_dump diğer kullanıcıların veritabanına (read veya write) erişimini engellemez.
- pg_dump kullanmak için özel bir yetki gerekmez; Normal bir kullanıcı bile, kullanıcının belirli bir veritabanı üzerinde izni olması koşuluyla onu çalıştırabilir.
- Alınan yedekler platform ve versiyon bağımsız olarak restore edilebilir.
pg_dump hakkında daha fazla ve detaylı bilgi almak için Tıklayınız.
1.1.2 pg_dumpall
Sıradaki komutumuz olan pg_dumpall
fonksiyonunun pg_dump
fonsiyonundan temel farkı, sadece bir veritabanı yerine komple veri tabanı kümesinin tüm içeriklerinin uygun şekilde yedeklenmesini sağlayabilmesidir. pg_dumpall
, verilen bir kümedeki her veri tabanının yedeğini ve verilen küme çapındaki rol ve tablo alanları tanımları gibi verilerin yedeğini de alır. Temel kullanımı şu şekildedir:
pg_dumpall > dumpfile
Örnek olarak tüm veritabanı kümemizin yedeğini aşağıdaki örnek kodla alalım.
pg_dumpall > yedekKume
pg_dumpall ile geri yükleme yaparken, rol ve tablo alanı bilgilerini de geri yüklemek için, her zaman superuser erişimine ihtiyaç vardır. Bu işlemleri yaparken, eğer tablo alanlarını kullanıyorsak, bu tablo alanlarının yollarının da var olduğundan emin olmamız gerekir.
Kısa bir özet ve ek olarak;
- Tüm veri tabanlarının yedeğini tek dosyaya alır. (cluster v.s.)
- Sadece düz metin olarak(text) yedek alır.
- Global bilgileri yedekler
- Özel olarak bir tablo yada bir veriyi açamazsınız(Geri Yüklenemez). Tüm veriler sadece bir texte yedeklenir.
- Global bilgileri ayrı olarak yedekleyebilirsiniz. Fakat önerilen pg_dumpta verileri yedekleyip sıkıştırılması ve pg_dumpall ile global bilgileri ayrı olarak yedeklenmesidir.
- INSERT yerine ön tanımlı olarak COPY yönetmi ile verileri yedekler. Sebebi ise COPY de Transaction oluşturulmaması, INSERT te ise oluşturulmasıdır.
Kullanım örnekleri;
# -g: sadece globalleri alır
# -r: Sadece kullanıcıları alır
# -a: DQL
# -s: DDL
pg_dumpall -g -f "FILE"
pg_dumpall hakkında daha fazla ve detaylı bilgi almak için Tıklayınız.
1.2 File System Level Backup
Alternatif bir yedekleme stratejisi olarak, PostgreSQL’in verileri veritabanında depolamak için kullandığı dosyaları doğrudan kopyalamaktan ibarettir. Örneğin data
dizini komple ayrı bir lokasyona kopyalanır. Dosya sistemi yedeklemeleri için herhangi bir kopyalama yöntemi kullanılabilir. Örneğin:
[WINDOWS]
xcopy "C:\Program Files\PostgreSQL\11\data" "D:\backup" /E
[LINUX]
cp -r /var/lib/pgsql/12/data /home/backup
Ardından, bu yedekten dönmek istediğinizde (restore) bu klasörde aynı sürüm adına sahip yeni bir sunucu örneği başlatabilirsiniz (bu komutu yönetici düzeyinde çalıştırmanız gerektiğini unutmayın):
[WINDOWS]
pg_ctl start -D "D:\backup"
[LINUX]
pg_ctl start -D /home/backup
Bu yöntem size aşağıdaki avantajları sağlar:
- Mantıksal yedeklemelerden (SQL dump) daha hızlı, basit dosya kopyalama kadar hızlı
- Tüm veritabanı kümesini yedekler
- Neredeyse anında kurtarma işlemi – Verileri geri almak için SQL komutlarının çalıştırılmasına gerek yoktur
Fakat bazı dezavantajları da mevcuttur:
- Veritabanının kapatılmasını gerektirir
- Yalnızca PostgreSQL’in aynı ana sürümünde geri yüklenebilir
- Sadece veritabanları veya sadece tablolar geri yüklenemez: Restore işleminde tümünü veya hiçbirini seçmelisiniz
- Tüm dizinleri içerdiği için çok büyük yedeklemeler üretir ve bu nedenle SQL dökümlerinden çok daha büyük boyutlarda olurlar
1.3 Continuous archiving
Sürekli arşivleme yöntemi, dosya sistemi düzeyinde bir yedeklemeyi (File System Level Backup) WAL dosyalarının (veritabanının veri dosyalarında yapılan her değişikliği saklayan yapı) yedeği ile birleştirir. Bu yedeklemeyi yönetmek, önceki yaklaşımların herhangi birine göre daha zordur, ancak bazı önemli avantajları vardır:
- Başlangıç noktası olarak mükemmel tutarlı bir dosya sistemi yedeklemesine sahip olmaya gerek yoktur. Günlüğün yeniden oynatılması, yedeklemedeki herhangi bir dahili tutarsızlığı düzeltir (bu, arıza kurtarma sırasında olanlardan önemli bir fark yaratmaz). Böylece, dosya sisteminin anlık görüntüsünü (snapshot) oluşturmanıza gerek kalmaz, sadece tar veya benzeri bir arşivleme aracı kullanırsınız.
- Sürekli yedeklemeler, yalnızca WAL dosyalarını arşivler. Bu, özellikle tam yedekleme yapmanın her zaman uygun olmadığı büyük veritabanları için değerlidir.
- WAL girişlerini sonuna kadar yeniden oynatmaya gerek yoktur. Tekrar oynatmayı herhangi bir noktada durdurabilir ve mevcut veritabanının tutarlı bir anlık görüntüsüne sahip olabilirsiniz. Bu nedenle, bu teknik sözde (PITR) “belirli bir noktada kurtarma” özelliğini destekler: Veritabanı, veritabanı yedeklemesinin yapılmasından bu yana herhangi bir zamandaki durumuna geri yüklenebilir.
- WAL dosyalarını, aynı temel yedekleme dosyasıyla yüklenmiş başka bir makineye sürekli olarak beslerseniz ve böylece hazırda bir bekleme sistemine sahip olursunuz (warm standby): ikinci makine, veritabanının neredeyse güncel bir kopyasıyla her zaman açılabilir.
Basit bir dosya sistemi yedekleme yönteminde olduğu gibi, bu teknik yalnızca bir veritabanı kümesinin tamamını geri yüklemeyi destekleyebilir, ancak bir alt kümeyi desteklemez. Ek olarak, bu yöntem büyük bir arşiv depolama alanı gerektirir: Temel bir yedekleme çok büyük olabilir ve yoğun bir sistem arşivlenmesi gereken büyük boyutlarda WAL trafiği oluşturabilir. Ancak bu, yüksek güvenilirliğin gerekli olduğu birçok durumda tercih edilen yedekleme yöntemidir.
Continuous archiving yöntemini ileride detaylı olarak ayrı bir başlıkta ele alacağız. Siz şimdilik incelemek için ilgili sayfaya gidebilirsiniz.
2. Yedekten Yükleme (Restore)
Herhangi bir arıza durumunda veya elinizdeki yedekler ile yeni bir kurulumda yedeğinizi rahatlıkla içeri aktarabilirsiniz. Bu başlıkta pg_dump
ve pg_dumpall
fonksiyonları ile aldığınız yedekleri nasıl restore edebileceğinizi göstereceğiz.Bu restore işlemi için pg_restore
komutunu kullanacağız.
Örnek olarak öncelikle custom-format bir dump aldığımızı varsayalım;
pg_dump -Fc mydb > db.dump
Ardından yedeği geri yüklemeden önce veritabanımızı kaldıralım ve yedekten yüklemeyi başlatalım. -C
komutu veritabanını yükleme yapmadan önce oluşturur. Bu parametre kullanıldığında dump dosyası içinde kullanılan veritabanı ismi baz alınır;
dropdb mydb
pg_restore -C db.dump
Veya daha basit olarak geri yüklemeden önce veritabanının otomatik silinip tekrar oluşturulması için -c
komutunu kullanabiliriz.
pg_restore -c db.dump
Restore işleminde veritabanını siz oluşturup, ismini özel olarakta belirtebilirsiniz.
createdb -T template0 newdb
$ pg_restore -d newdb db.dump
Kısa bir özet olarak;
- pg_restore sadece sıkıştırılmış yedekleri geri yükleyebilir.
- Aynı anda 4 paralel geri yükleme yapabilir.
- -j komutuyla kaç paralel yükleme yapacağını söyleyebilirsiniz.
Ayrıca ek olarak kullanabileceğiniz tüm parametreler şunlardır;
-d
, database-h
, hostname-p
, Port numarası-U
, belirtilen veritabanı kullanıcısı-w
, Şifresiz işlem yapar.-a
, şemayı değil sadece veriyi yükler.-c
, yükleme yapmadan önce veritabanını siler.-C
, yükleme yapmadan önce veritabanını oluşturur. –c ile kullanıldığında önce veritabanını siler sonra tekrar oluşturur.-f
, yedek dosyası ve yer aldığı dizin adı.-F c | d | t | p
, yedek dosya formatı (custom, directory, tar, düz metin (varsayılan)).-I
, belirtilen index veya indexleri yükler.-n
, yalnızca belirtilen şemada ki nesneleri yükler.-O
, nesne sahipliklerini atlayarak yükleme yapar.-P
, belirtilen fonksiyon veya fonksiyonları yükler.-s
, sadece şema yüklemesi yapar, dataları değil.-t
, belirtilen tablo veya tabloları yükler.-T
, -belirtilen trigger veya triggerları yükler.-v
, yükleme yapılırken ayrıntılı modu belirtir.-V
, pg_restore sürüm bilgisini verir.
pg_restore hakkında daha fazla ve detaylı bilgi almak için Tıklayınız.
3. Büyük Veri Tabanlarında Kullanım
(Bu başlık şu makaleden bölüm alıntılanmıştır)
pg_dump sonucunda dosya oluştuğunda, bazı işletim sistemlerinde var olan maksimum dosya boyut sınırından dolayı bazı problemlerle karşılaşabiliriz. pg_dump bu noktada bize birtakım çözümler sunuyor:
3.1 Sıkıştırmak (gzip)
pg_dump dbname | gzip > filename.gz
Bu şekilde sıkıştırılmış olarak oluşturacağımız gibi, aşağıdaki gibi bunları yeniden yükleyebiliriz:
gunzip -c filename.gz | psql dbname
ya da cat filename.gz | gunzip | psql dbname
3.2 Split
Diğer yöntem ise parçalamak. Split komutu, oluşacak dosyaları küçük dosyalara bölerek kaydetmemizi sağlar. Örneğin, 1 megabyte olarak parçalamak isteyelim:
pg_dump dbname | split -b 1m - filename
Yeniden yüklemek için;
cat filename* | psql dbname
3.3 pg_dump’ un özel yedekleme formatı
Eğer PostgreSQL, zlip sıkıştırma kütüphanesinin kurulu olduğu bir sisteme kurulduysa, bu özel format, verileri, çıktı dosyasına sıkıştırılmış olarak yazacak. Bu işlem, gzip kullanıldığında oluşacak olan dosya boyutuna yakın boyutlarda bir dosya üretecektir. Ama asıl avantajı, sadece seçtiğimiz tabloları geri yükleyebilmemizdir. Basit kullanımı:
pg_dump -Fc dbname > filename
Bu özel format, psql için bir script değildir. Onun yerine pg_restore kullanılır:
pg_restore -d dbname filename
Örneğin, dvdrental veri tabanı içerisindeki, sadece actor tablomuzu yedekten dönmek istiyoruz:
pg_restore -t actor -d dvdrental C:\temp\dvdrental_v1
Bu komut sonrasında dvdrental_v1 yedek dosyamızdan, sadece actor tablosunu geri yüklemiş oluruz.Çok büyük veri tabanları için, split ile diğer seçenekleri birleştirmeye de ihtiyaç duyulabilir.
3.4 pg_dump kullanarak paralel yedek alma
Büyük bir veri tabanının yedekleme hızını artırmak için, pg_dump’un paralel modunu kullanabiliriz.Bu sayede, birden fazla tabloyu aynı anda yedekleyebiliriz. -j parametresi ile bu paralelliğin derecesini yönetebiliriz. Bu yöntem sadece dizin(directory)
arşiv formatını destekler.
pg_dump -j num -F d -f out.dir dbname
Örnek:
pg_dump -j 1 -F d -f C:\temp\a\dvdrental_v1 dvdrental
-F, formatı belirtir; p-c-d-t gibi seçenekleri vardır (directory).
pg_restore -j 1 -d dvdrental C:\temp\a\dvdrental_v1
Paralel olarak bir yedeği geri yüklemek için pg_restore -j komutunu kullanabiliriz. Bu, pg_dump -j ile oluşturulmayanlar için de geçerlidir.