Basebackup & Restore

Online (Hot) Backup, pg_basebackup

Postgresql veritabanı çalışırken yani instance açıkken pg_basebackup ile yedeği
alınabilir.
Yedek işlemi sırasında kullanıcılar etkilenmez ve bu yedek ile hem tam geri yükleme
(full recovery) hem de belirli bir ana (point-in recovery) geri yükleme yapılabilir. Ek
olarak bu yedek hot standby kurulumu için de kullanılabilir.

Basebackup, veritabanını otomatik olarak backup moda alır ve tüm cluster dizinini
kopyalar. Tek bir veritabanını ya da bir iki objesinin yedeğini alamaz, tüm veritabanlarını
tüm objeleri ile yedekler. Seçili objelerin yedeği için pg_dump kullanılabilir.

Backup, replikasyon protokolünü kullanan postgresql bağlantısı üzerinden yapılır.
Backup alacak kullanıcının replication ya da superuser haklarına sahip olması gerekir ve
pg_hba.conf dosyasında erişim izni verilmelidir.

Aynı anda birden fazla pg_basebackup çalıştırılabilir ama IO kaynaklı darboğaza
düşmemek için tavsiye edilen tek tek çalıştırmaktır. (Veya ilk alınan backup
kopyalanabilir.)

pg_basebackup ile primary sunucudan da standby sunucudan da backup alınabilir.
Standby sunucudan backup almanın bazı kısıtları vardır. Detay için resmi kılavuz
sayfasına bakınız.

# fullbackup, /RA/bb dizinine sıkıştırılarak yedekleme
pg_basebackup -D /RA/bb -c fast -l "'date'" -P -F tar -z -X fetch -R
-D
(directory)
Yedek alınacak klasörü adresler, klasör yok ise oluşturur. İçi boş
olmalıdır.
-l (label)Alınan yedeği etiketler.
-P (progress)Yedekleme işlemini yüzdelik dilimlerle raporlar.
-FFormat seçimini yapar;
p (plain) seçilirse birebir dizin yapısını kopyalar. Sadece default
tablespace’lerin bulunduğu veritabanlarında tüm veritabanı
hedef dizine yedek alınmış olur.
Eğer ek tablespace’ler var ise -tablespace-mapping
parametresi kullanılmalıdır.
t (tar), tar formatında arşivleyeyerek yedek alır. Ana klasör
base.tar, tablespace’ler de $OID.tar şeklinde isimlendirilir.
-z (gzip)tar formatında alınan yedekleri gzip ile sıkıştırır. Uzantısı
otomatik olarak …tar.gz olur. -Z ile sıkıştırma oranı (0-9) verilebilir.
-c fastFast checkpoint modunu belirler. pg_basebackup
çalıştırıldığında checkpoint işlemini bekler, bu sırada
çalışmıyormuş izlenimi verebilir.
fast ile checkpoint işleminin anında gerçekleştirilmesi sağlanır.
Böylece yedekleme hemen başlar aksi halde gelecek checkpoint
işlemini beklemek gerekir. spread modu için postgresql resmi
klavuzu bölüm 25.3.3’ e bakınız.
-X (method)WAL dosyalarının yedeklenmesi ile ilgili metod belirtilir.
n (none), WAL dosyalarını yedeklemez.
f (fetch), WAL dosyalarını, yedekleme işleminin sonunda
alır.
Yedekleme bitmeden, gerekli olan WAL dosyalarının silinmemesi
için wal_keep_size parametresi ile yeteri kadar alan tahsis
edilmelidir. Eğer yedek tamamlanmadan, gerekli olan WAL
silinirse yedek hata alır ve o yedek kullanılamaz.
tar formatında yedek alınırsa WAL dosyaları base.tar ‘ ın
içerisinde yer alır.
s (stream), Yedek başladığında 2. bir bağlantı açar ve
yedeklemeye paralel olarak WAL dosyalarını stream yöntemi ile
dizine alır.
tar metodu kullanılıyorsa pg_wal.tar olarak yedeklenir.
(postgresql 10 öncesi ise pg_xlog.tar)
-R (-writerecoveryconf)standby.signal dosyasını oluşturur. Standby kurulumunu
kolaylaştırmak için postgresql.auto.conf dosyasına
primary_conninfo bilgilerini ekler.
-T
(-tablespacemapping=
önceki
klasör=yeniklasör)
Yedek alırken tablespace’in klasörünü yeniden konumlandırır.
Klasörlerin tam yolu girilmelidir. Yeni klasör, öncesinde
oluşturulmalı ve boş olmalı. Tablespace yeniden
konumlandırıldığında linkler de güncellenerek yeni klasörleri
adresliyor olacaktır.
-r (rate)Saniyede gerçekleştirilebilecek maximum veri transferini
limitler. Sürekli yoğun olan veritabanlarında işleyişi etkilememek
için kullanışlı olabilir. Default birim KB’dir ama M ile MB
cinsinden ayarlanabilir (örn: 100M saniyede 100MB’nin üzerine
çıkılamayazağını ifade eder).
-v (verbose)verbose mod, daha detaylı log çıktısı verir.
-h (host) , -p (port), -U (username), -W (password) gibi
parametrelerle network üzerindeki veritabanlarının yedeği alınabilir. Bunun için
postgresql client kurulmalıdır.
# Günün tarihini ve yedekleme zamanını içeren dizine yedekleme
CURDATE=`date +%H%M_%d%m%y`
BCKDIR=/RA/basebackup
LOG=$BCKDIR/basebackup_${CURDATE}.log
pg_basebackup -D $BCKDIR/$CURDATE -c fast -v -l “`date`” -P -F
tar -z -X fetch -R &>> $LOG

# veya

pg_basebackup -D $BCKDIR/$CURDATE -c fast -v -l “`date`” -P -F
tar -z -X stream -R &>> $LOG

/RA/basebackup/$SaatDakika_GünAyYıl isimli klasöre tar.gz uzantılı
yedeği alıp gene aynı dizine logu yazar.
Yedeğin işe yarayabilmesi için yedek sırasında ve sonrasında oluşan WAL dosyalarına
ihtiyaç vardır. Yedeğin başlangıç noktasını imlemek için WAL dosyasının isminde
.backup uzantısı ekleyerek bir text dosyası oluşturur. Label, başlangıç ve bitiş noktası
gibi bilgileri yazar.

Yedekten Geri Yükleme (Restore & Recovery)

# Full backup alınır.
pg_basebackup -D /RA/basebackup/fullbackup -l "'date'" -c fast -P -v -F
tar -z -X fetch -R
# Backup içeriği
postgres@srv1:~$ ls -hs1 /RA/basebackup/fullbackup/
932K 33016.tar.gz
4.0K 33024.tar.gz
4.0K 33029.tar.gz
616K backup_manifest
54M base.tar.gz
# Tablespace OID’leri
postgres=# select * from pg_tablespace ;
oid   | spcname    | spcowner | spcacl |
-------+------------+----------+--------+
1663  | pg_default | 10       |        |
1664  | pg_global  | 10       |        |
33016 | erp_tbs    | 10       |        | ---> /erp
33024 | ik_tbs     | 16486    |        | ---> /ik
33029 | tmp_tbs1   | 10       |        | ---> /tmp_tbs

tar formatında sıkıştırarar yedek alınır. Default tablespace ler base.tar.gz
içerisinde yer alırken sonradan oluşturulan tablespace ler kendi OID’leri ile ayrı
dosyalara yazılır.
Veritabanının cluster dizini yani PGDATA = /pg/data/13.6
ve wal dosyaları /RA/archive dizinine alınıyordu.
PGDATA, /erp ve /ik dizinlerinin biri ya da bir kaçına erişilemiyorsa,
Yazılmakta olan WAL/veri dosyası silinmiş ya da bozulmuşsa (corrupt) full recovery yani
yedek tam geri yükleme yapmak gerekir.

Yedekten Geri Yükleme (Restore & Recovery)

# Senaryo gereği /pg/data/13.6, /erp, /ik ve /tmp_tbs dizinleri silinir.
postgres@srv1:~$ rm -rf /pg/data/13.6/*
postgres@srv1:~$ rm -rf /erp
postgres@srv1:~$ rm -rf /ik
postgres@srv1:~$ rm -rf /tmp_tbs
postgres@srv1:~$ pkill postgres

Adım 1

# Recovery işlemlerini geçilir. Klasörlerin sahibi postgres
kullanıcısı olmaldır.
postgres@srv1:/$ sudo mkdir /erp
postgres@srv1:/$ sudo chown -R postgres:postgres /erp
postgres@srv1:/$ sudo mkdir /ik
postgres@srv1:/$ sudo chown -R postgres:postgres /ik
postgres@srv1:/$ sudo mkdir /tmp_tbs
postgres@srv1:/$ sudo chown -R postgres:postgres /tmp_tbs/

Gerekli klasörler oluşturulur. Eğer farklı bir makineye yedekten geri yükleme yapılacaksa
önce postgresql 13.6 sürümü (yani yedek alınan postgresql ile aynı sürüm) kurulması
gerekir (initdb çalıştırmadan). 1. bölümde kaynak koddan 16. bölümde ise apt ile
hazır paketlerden kurulum anlatıldığı için burada tekrar değinilmemiştir.

Adım 2

# Orijinal lokasyonlara veri dosyaları restore edilir.
tar xvf /RA/basebackup/fullbackup/base.tar.gz -C /pg/data/13.6/
tar xvf /RA/basebackup/fullbackup/33016.tar.gz -C /erp
tar xvf /RA/basebackup/fullbackup/33024.tar.gz -C /ik
tar xvf /RA/basebackup/fullbackup/33029.tar.gz -C /tmp_tbs/

# İşletim sistemi ile kopyalanan wal dosyaları silinir ve
arşivlenmiş wal dosyaları kopyalanır.
postgres@srv1:/$ rm -rf /pg/data/13.6/pg_wal/*
postgres@srv1:/$ cp /RA/archive/* /pg/data/13.6/pg_wal/

tar dosyaları orijinal lokasyonlara çıkarılır (extract) . Burada dikkat edilmesi gereken
nokta, hem yedek için hem de veri için disk alanına ihtiyaç vardır. 100’lerce terabyte
verinin olduğu ortamlarda sorun olabilir. Bu yüzden işlemlere başlamadan ihtiyaç
duyulan disk alanları hesaplanmalıdır. Senaryosu çizilmelidir. Network hızı yeterli ise
yedeklerin bulunduğu diskler network üzerinden sisteme gösterilebilir (NFS mount).

Adım 3

ln -s /erp /pg/data/13.6/pg_tblspc/33016
ln -s /ik /pg/data/13.6/pg_tblspc/33024
ln -s /tmp_tbs /pg/data/13.6/pg_tblspc/33029

Linkler oluşturulur. /pg/data/13.6/tablespace_map dosyasında OID ve
klasör bilgileri gelir.

Adım 4

postgres@srv1:/$ rm /pg/data/13.6/standby.signal
postgres@srv1:/$ touch /pg/data/13.6/recovery.signal
postgres@srv1:/$ vim /pg/data/13.6/postgresql.conf
restore_command = ‘cp /RA/archive/%f “%p”’
recovery_target_timeline = ‘latest’

Recovery modda başlatmak için $PGDATA dizininde recovery.signal dosyası
oluşturulup standby.signal silinir. Her iki dosya aynı anda bulunursa standby
mod ak
tif olur.
postgresql.conf dosyasına restore_command ve recovery_target_
timeline parametreleri eklenir.
Not: Versiyon 12 öncesinde bu parametreler recovery.conf dosyasına yazılırdı.
recovery_target = ‘immediate’ eklenirse tutarlı (consistent) bir noktaya
ulaşır ulaşmaz recovery işlemini sonlandırıp instance’ı açar.

Adım 5

postgres@srv1:~$ which pg_ctl
/pg/home/13.6/bin/pg_ctl
pg_ctl -o ‘--config-file=/pg/data/13.6/postgresql.conf’ -D /pg/
data/13.6/ -l pg.log start
“tail -f postgresql-Sat.log” düşen loglar incelenir.
starting PostgreSQL 13.6 on x86_64-pc-linux-gnu, compiled by gcc
(Debian 8.3.0-6) 8.3.0, 64-bit
listening on IPv4 address “0.0.0.0”, port 5434
listening on IPv6 address “::”, port 5434
listening on Unix socket “/tmp/.s.PGSQL.5434”
database system was interrupted; last known up at 2022-08-13 12:20:41
+03
cp: cannot stat ‘/RA/archive/00000002.history’: No such file or
directory
starting archive recovery
restored log file “00000001000000000000004D” from archive
redo starts at 0/4D000028
consistent recovery state reached at 0/4D000138
database system is ready to accept read only connections
cp: cannot stat ‘/RA/archive/00000001000000000000004E’: No such file or
directory
redo done at 0/4D000138
restored log file “00000001000000000000004D” from archive
cp: cannot stat ‘/RA/archive/00000002.history’: No such file or
directory
selected new timeline ID: 2
archive recovery complete
cp: cannot stat ‘/RA/archive/00000001.history’: No such file or
directory
database system is ready to accept connections

Archive recovery için tüm hazırlıklar tamamlandıktan sonra instance açılır
(kurulumunuza bağlı olarak systemctl ya da manuel pg_ctl ile) .
postgresql.conf’daki restore_command ve recovery_target_timeline
parametrelerinin başına # eklemekte fayda var.

Kategori seçin...