Bu yazımda,Centos 7 üzerine Postgresql 12 streaming replikasyon kurulumunu anlataya çalışacağım. Bu kısma devam etmeden önce eğer okumadıysanız repliksayon ile ilgili yazdığım yazıyı okumanızı tavsiye ederim.

Hostname IP Açıklama
primary 192.168.10.105 Primary Cluster
standby 192.168.10.106 Standby Cluster

Primary Sunucu İşlemleri

Öncelikle primary sunucu üzerine clustarımızı kuralım.

yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

yum install -y postgresql12 postgresql12-server postgresql12-contrib

/usr/pgsql-12/bin/postgresql-12-setup initdb
systemctl enable postgresql-12
systemctl start postgresql-12 

Standby üzerinden primary sunucuya bağlanmak için  REPLICATION rolüne sahip kullanıcı oluşturulur.

CREATE ROLE replicationuser WITH LOGIN PASSWORD '112233ee' REPLICATION;

--\du komutu  ile kullanıcıları görebiliriz 

Oluşturduğumuz replica_user kullanıcısının erişimi için pg_hba.conf dosyasını düzenlememiz gerekiyor. pg_hba.conf dosyasında yapılan bir değişikliğin etkin olabilmesi için Postgres sunucusu reload işlemine ihtiyaç duyar.

echo "host    replication     replicationuser 192.168.10.106/32   md5">>/var/lib/pgsql/12/data/pg_hba.conf

--Aşağıdaki komutlardan birini kullanarak reload işlemini yaparız;
SELECT pg_reload_conf();
pg_ctl reload
systemctl reload postgresql-12 

PostgreSQL varsayılan olarak localhost adresini dinler. Dışardan gelen talepleri dinleyecek IP adresini yazabileceğimiz gibi * işaretini koyarak sunucudaki tüm ip adreslerini dinlemesinide sağlayabiliriz. Ayrıca değiştirmek istersek varsayılan olarak gelen 5432 portunu düzenlemeliyiz, ben portu değiştirmeden devam ediyorum.

listen_addresses = '*'
port = 5432 

postgresql.conf dosyasında yer alan wal_level, max_wal_senders, max_replication_slots parametrelerinin değerleri postgresql-10 sürümünden itibaren varsayılan olarak replikasyon işlemi için ayarlanmış olarak gelir;

  • wal_level : wal_level parametresi ile WAL’a ne kadar bilgi yazılacağını belirler. Varsayılan değer, yedek bir sunucuda salt okunur sorguların çalıştırılması dahil, WAL arşivlemeyi ve çoğaltmayı desteklemek için yeterli veriyi yazan replica’dır. minimal, bir çökme veya anında kapanma durumundan kurtarmak için gereken bilgiler dışındaki tüm log kaydını kaldırır. logical, logical decoding için gerekli bilgileri ekler.
  • max_wal_senders :  Eş zamanlı olan replikasyon bağlantısı sayısını belirtir. Bu sayı en az slave sunucu sayısı +1 olmalıdır. Varsayılan 10’dur. 0 değeri, replikasyonun devre dışı bırakıldığı anlamına gelir. Standby sunucu çalıştırırken, bu parametreyi primary sunucudakiyle aynı veya daha yüksek bir değere ayarlamalısınız. Aksi takdirde, standby sunucusunda sorgulara izin verilmeyecektir.
  • max_replication_slots : Sunucunun destekleyebileceği maksimum replikasyon slot sayısını Varsayılan 10’dur. Mevcut slot sayısından daha düşük bir değere ayarlamak, sunucunun başlamasını engeller.

Bu parametrelerin dışında primary sunucuda replikasyon ile ilgili aşağıdaki paramtreleride düzenleyebiliriz, özellikle varsayılan olarak gelen asenkron replikasyonu değiştimek istersek synchronous_standby_names parametresini düzenlemeliyiz;

  • wal_keep_segments : pg_wal’da tutulan minimum segment sayısını yani kaç tane wal dosyası tutulacağını belirler; sistemin WAL arşivlemesi için veya checkpoint’den sonra kurtarmak için daha fazla segment tutması gerekebilir.replication slot kullanılarak, replikasyon için bu paramtreye olan bağımlılığımızı ortan kaldırabiliriz.
  • wal_sender_timeout : Belirlenen süreden daha uzun süre etkin olmayan replikasyon bağlantılarını sonlandırır. Bu, primary sunucu ile standby sunucu arasında ağ ile ilgili problemin algılaması için kullanışlıdır. Varsayılan değer 60 saniyedir. Sıfır değeri, zaman aşımı mekanizmasını devre dışı bırakır.
  • track_commit_timestamp : transactionların commşt süresini kaydededer.
  • synchronous_standby_names : Senkron replikasyonu destekleyebilen standby sunucularının listesini belirtir. Bu parametreyi örnekler ile anlatmanın daha yararlı olacağı düşüncesindeyim;

Varsayılan olarak gelen bu kullanımda senkronizasyon kapalıdır.

 synchronous_standby_names = ''

Bu kullanımla kullanıcı primary sunucuda transaction commit yaptığında onay mesajının gitmesi için aşağıdaki 3 sunucuyada verinin senkron olması gerekir.

 synchronous_standby_names = '(node1, node2, node3)'

Bu kullanımda kullanıcı primary sunucuda transaction commit yaptığında onay mesajının gitmesi için aşağıdaki 5 standby sunucudan en az 3’ünün senkronize olması gerekir.

 synchronous_standby_names = '3 (node1, node2, node3, node4, node5)'
synchronous_standby_names = '2 (*)'

Bu kullanımda kullanıcı primary sunucuda transaction commit yaptığında onay mesajının gitmesi için aşağıdaki 5 standby sunucudan en az 3’ünün senkronize olması gerekir.

 synchronous_standby_names = 'any 3(node1, node2, node3, node4, node5)'

Bu kullanımda kullanıcı primary sunucuda transaction commit yaptığında onay mesajının gitmesi için aşağıdaki 5 standby sunucudan en az 2’ünün senkronize olması gerekir. Fakat bunun ANY’den farkı yazım sıramıza göre sunuculara priority veriyor, yani bu kullanımda her zaman ilk 2 sunucuyu senkron etmeye çalışacak ama bu sunuculardan birine erişemeyince bir sonrakine senkron etmeye çalışacak.

 synchronous_standby_names = 'first 2(node1, node2, node3 node4, node5)'

Stadnby Sunucu İşlemleri

Öncelikle standby  sunucu üzerine clustarımızı kuralım, burada bilmemiz gereken standby sunucudaki cluster’da initdb yapmamızdır.

yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

yum install -y postgresql12 postgresql12-server postgresql12-contrib 

pg_basebackup komutunu kullanarak master sunucu üzerinde bulunan PostgreSQL data dizininin bir kopyasını replica sunucuya alalım.

/usr/pgsql-12/bin/pg_basebackup -D /var/lib/pgsql/12/data/ -Fp -R -X stream -c fast -C -S standby01 -h 192.168.10.105 -U replicationuser -P 
Parametre Açıklama
-D Çıktının yazılacağı dizin.
-Fp -F parametresi çıktı formatını belirler.p ise plain anlamındadır. Plain ile gelen veri primary sunucuda nasılsa standby sunucudada aynı şekilde yerleştirilir. Burada alternatif olarak istenirse p yerine t kullanılarak gelen veriler tar lanabilir.
-R Bağlantı ayarlarını çıktı dizinindeki postgresql.auto. ekler. postgresql.auto.conf dosyası, bağlantı ayarlarını ve belirtilirse, pg_basebackup’ın kullandığı replication slotı kaydeder, böylece streaming replikasyon daha sonra aynı ayarları kullanır.
-X WAL kayıtlarını toplamak için gerekn yöntemi seçmemizi sağlar. Varsayılan olarak gelen stream ile yedekleme yapılırken ikinci bir bağlantı açacak ve WAL kayıtlarını paralel olarak almaya başlayacaktır.
-c Checkpoint modunu ayarlar.İstersek fast diyerek anında olmasını sağlayabiliriz yada varsayılan olarak gelen spread ile zamana da yayabiliriz.
-h Sunucunun çalıştığı makinenin adını belirtir. Varsayılan, PGHOST ortam değişkeninden alını.
-C Bu seçenek, yedeklemeye başlamadan önce –slot seçeneği ile adlandırılan bir replication slot oluşturulmasına neden olur. Slot zaten mevcutsa bir hata oluşur.
-S Bu seçenek yalnızca -X stream ile birlikte kullanılabilir. WAL streamın belirtilen replication slot kullanmasına neden olur.
-U Bağlantı sağlayacak veritabanı kullanıcısı.
-P Yedekleme  raporlamasını etkinleştirir.

 

Örnek çıktı aşağıdaki gibidir.

 -bash-4.2$ /usr/pgsql-12/bin/pg_basebackup -D /var/lib/pgsql/12/data/ -Fp -R -X stream -c fast -C -S standby01 -h 192.168.10.105 -U replicationuser -P
Password: 
25316/25316 kB (100%), 1/1 tablespace

Postgresql 12’den önce pg_basebackup komutunda yer alan -R parametresi ile eskiden recovery.conf dosyasına yazılan recovery ayarları artık postgresql-auto.conf dosyasına yazılır;

-bash-4.2$ cat postgresql.auto.conf 
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=replicationuser password=112233ee host=192.168.10.105 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'standby01' 

NOT : Replikasyon sayısının fazla olduğu yerlerde takibi kolaylaştırmak adına postgresql-auto.conf’da primary_conninfo parametresine application_name ekleminizi tavsiye ederim.

 primary_conninfo = 'application_name=standby01 user=replicationuser password=112233ee host=192.168.10.105 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres

NOT : Postgresql 12’den önce bulunan recovery.conf dosyasında yer alan “standby_mode” parametresi yerine replikasyondaki /var/lib/pgsql/12/data dizini içinde standby.signal dosyası getirildi.

Artık standby veritabanımız hazır, postgresql’i çalıştırıp replikasyonu başlatabiliriz.

 systemctl enable postgresql-12 systemctl start postgresql-12

Standby sunucu üzerinde veritabanına psql ile bağlanarak replikasyonun çalıştığını pg_stat_wal_receiver viewini kullanarak aşağıdaki gibi kontrol edebilirsiniz.

Postgresql Replikasyon

Primary sunucu üzerinde replikasyonu kontrol etmek istersek pg_stat_replication viewini kullanarak aşağıdaki gibi kontrol edebilirsiniz.

Postgresql Replikasyon 2

Ayrıca sunucularda çalışan WAL sender/receiver proseslerini de görebiliriz.

 [root@primary ~]# ps -ef | grep wals | grep -v grep postgres 57470 57422 0 21:33 ? 00:00:00 postgres: walsender replicationuser 192.168.10.106(49606) streaming 0/5019398 [root@standby ~]# ps -ef | grep walr | grep -v grep postgres 55069 55062 0 21:33 ? 00:00:01 postgres: walreceiver streaming 0/5019398

Replikasyonun ne kadar güncel olduğunu kontrol etmenin bir yolu, primary’de oluşturulan ancak standby’de henüz uygulanmamış WAL kayıtlarının miktarını kontrol etmektir.

 postgres =# SELECT pg_current_wal_lsn(); -[ RECORD 1 ]------+---------- pg_current_wal_lsn | 0/5019398
postgres=# SELECT pg_last_wal_receive_lsn();
-[ RECORD 1 ]-----------+----------
pg_last_wal_receive_lsn | 0/5019398 

Saniye cinsinden gecikmeyi öğrenmek için aşağıdaki sorguyu kullanabiliriz.

postgres=# SELECT CASE WHEN pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn() THEN 0 ELSE EXTRACT (EPOCH FROM now() - pg_last_xact_replay_timestamp()) END AS log_delay; log_delay ----------- 17.998835 (1 row) 

En son kurtarılan wal kaydının zamanını öğrenmek için;

select pg_last_xact_replay_timestamp();

Standby sunucuda replikasyonu durdumak için aşağıdaki fonksiyondan yararlanabiliriz.

select pg_wal_replay_pause();

Standby sunucuda replikasyonu devam ettirmek için aşağıdaki fonksiyondan yararlanabiliriz.

select pg_wal_replay_resume();

Standby sunucuda recovery’nin durdurulup durdurulmadağını aşağıdaki fonksiyon ile öğrenebiliriz.Eğer standby recovery devam ediyorsa false yani f recovery durmuşsa true tani t çıktısını alırız.

pg_is_wal_replay_paused();

Bağlandığımız sunucunun Standby mı Primary mi olduğunu öğrenmek için aşağıdaki fonksiyonu kullanırız. Recovery devam ediyorsa true kısaca t döner buradan da standby sunucu olduğunu anlarız, eğer false kısaca f dönerse recovery olmadığını yani primary olduğunu varsayabiliriz.

select pg_is_in_recovery();

Detaylarına daha sonra değinezeğiz ama derli toplu olsun diye burayada yazmak istedim. pg_promote(), standby sunucuyu primary konuma yükseltmek veya standby sunucuyu read-only kurtarma modundan çıkarıp read-write moduna geçirmek için bir PostgreSQL fonksiyonudur. pg_promote iki farklı argüman verilerek kullanılabilir.
true veya false değeri verilerek fonksiyon çalıştırılabilir(hiçbir parametre vermessek varsayılan olarak true değerini alır).
Yükseltmenin gerçekleşmesi için kaç saniye bekleneceği varsayılan olarak 60 saniyedir.

select pg_promote();
SELECT pg_promote(true, 30);
SELECT pg_promote(false);

İhtiyacımıza göre standby sunucu üzerinde aşağıdaki parametreleride kullanabiliriz;

  • recovery_min_apply_delay (integer) : Varsayılan olarak, standby sunucusu, WAL kayıtlarını gönderen sunucudan mümkün olan en kısa sürede recovery yapar. Veri kaybı hatalarını düzeltme fırsatları sunan, verilerin gecikmeli bir kopyasına sahip olmak yararlı olabilir. Bu parametre, kurtarmayı belirli bir süre geciktirmenize olanak tanır. Örneğin, bu parametreyi 5 dakikaya ayarlarsanız, standby, her transaction kaydını en az beş dakika geçtiğinde yeniden oynatır. Bu değer birimsiz belirtilirse milisaniye olarak alınır. Varsayılan sıfırdır, gecikme yoktur. Gecikmenin, aprimary sunucuda yazılı olan WAL zaman damgası ile standby modundaki geçerli saat arasında hesaplandığını unutmayın.
  • hot_standby (boolean) : Standby sunucu sorgu çalıştırıp çalıştırmayacağınızı belirtir yani read only olarak kullanıp kullanamıyacağımız bu parametreye vağlıdır. Varsayılan değer açıktır.
  • promote_trigger_file (string) : Standby modunda recoveryi sona erdiren tetikleyici bir dosya belirtir. Bu değer ayarlanmasa bile, pg_ctl promote kullanarak veya pg_promote’u çağırarak standby’ı yine de read write olarak açabiliriz.
  • wal_receiver_status_interval (integer) : Yedekleme ilerlemesi hakkındaki bilgileri pg_stat_replication viewi kullanılarak görülebileceğini söylemiştik bu bilgiler WAL receiver aracılığıyla elde edinilir, işte bu parametre WAL receiver prosesinin çalışma sıklığını belirtir. WAl receiver ile standby, eline ulaşan son wal konudmu ile birlikte diske yazdığı wal kaydını ve recovery ettiği wal kayıt bilgilerini primary’e iletir. Bu parametrenin değeri, raporlar arasındaki maksimum süredir. Update, write gibi ifadeler çalıştığında zaten bu proses tetiklenir ama sunucuda hiçbir işlem yapılmasa bile maksimum belirtilen sürede proses tetiklenecek. Varsayılan değer 10 saniyedir. Bu parametrenin sıfır olarak ayarlanması, durum güncellemelerini tamamen devre dışı bırakır.
  • wal_receiver_timeout (integer) : Bu süreden daha uzun süre etkin olmayan replikasyon bağlantılarını sonlandırır. Bu standby ile primary sunuculardan birinin çökmesini veya ağ kesintisini algılaması için kullanışlıdır. Varsayılan değer 60 saniyedir.
  • wal_retrieve_retry_interval (integer) : Standby sunucusunun, WAL verilerini geri almayı tekrar denemeden önce, herhangi bir kaynaktan (streaming replikasyon, local pg_wal veya WAL archive) WAL verileri mevcut olmadığında ne kadar beklemesi gerektiğini belirtir. Varsayılan değer 5 saniyedir.

Mustafa Bektaş Tepe
İyi Çalışmalar

Referanslar;
https://www.tecmint.com/configure-postgresql-streaming-replication-in-centos-8/
https://medium.com/@aydemirzekiye/postgresql-12de-streaming-replication-i%CC%87%C5%9Flemleri-40f792a8141b
https://blog.gunduzdanismanlik.com/
https://www.enterprisedb.com/blog/high-availibility-parameters-configuration-streaming-replication-postgresql

Loading