Postgresql BFM otomatik failover ve switch over özelliği olan bir HA (High Availability) ürünüdür. Ürün çalışmasını mantık olarak kısaca özetleyecek olur isek, Postgresql bir tane master sunucumuz ve bunun replica ları olan slave sunucularımız mevcuttur, master sunucuda herhangi bir problem yaşandığında otomatik olarak switch olacak ve diğer sunucumuz artık master olarak devam edecek, eski sunucu eğer tekrar çalışır ise oda sistemde artık slave olarak çalışmaya devam edecektir. Burada ki çalışma şeklinde bir VIP (Virtual IP) olacak ve bu VIP IP her zaman master üzerinde çalışacak switchover ve failover senaryolarında VIP master üzerinde taşınmaktadır.
Peki bu işler nasıl gerçekleşir kısaca açıklayalım
- VIP Virtual IP
- Sadece Master Sunucuda aktif olarak çalışmaktadır
- Tüm kullanıcılar VIP IP üzerinden bağlantı kurar.
- Failover veya swithcover sonrasında pasif sunucuda etkinleşir
- BFM watcher ne iş yapar
- Tüm nodları sürekli kontrol eder
- Herhangi bir node çalışmaz ise bunu minipg ye haber verir
- Tüm nod lardan sadece bir tanesinde bfm aktif olarak çalışır diğer bfm ler dinleme modundadır.
- Minipg ne yapar?
- Switchover ve Failover işlemlerinin komutlarını çalıştırır
- Eski master sunucu çalıştırıldığında tekrar slave olarak eklenmesini sağlar. (Rewind)
- VIP Ip up-down işlemleri.
Buradaki VIP IP eğer farklı subnet ortamlarında ise bunun için bir witness server kullanılır, 2 farklı subnette tanımlı 2 farklı VIP Ip tanımlanır, bu VIP IP ler kullanılır, witness server üzerinden nginx TCP balance kullanılarak Failover ve Switchover operasyonları gerçekleştirilir.
Yeni versiyonunda SSL desteklenmektedir, ayrıca Network Heartbeat özelliği sunulmaktadır. Konfigürasyon dosyalarında kullanıcı ve şifre bilgileri şifreli olarak saklanabilmektedir. Diğer HA ürünlerinde bu ssl desteği bulunmaktadır, BFM bu yüzden bankacılık gibi hassas ve güvenliğin ön planda olduğu kurumlar tarafından tercih edilmektedir, bu ürün bankalar tarafından kullanılmakta ve bankacılık güvenlik testlerinden geçmiş bir üründür.
Ürün özellikleri yukarıda ki gibidir, şimdiBFM i kurulumunu yaparak testlerini gerçekleştirelim.
Kurulum için 2 Adet RedHat 8 sunucu kullanacağım. Öncelikle Postgres Kurulumlarımızı yapıyoruz.
OS | PostgresSQL | IP | VIP IP |
RedHat8 | PostgreSQL 13 | 192.168.5.132 | 192.168.5.140 |
RedHat 8 | PostgreSQL 13 | 192.168.5.133 | 192.168.5.140 |
RedHat 8 (Centos 8 & Oracle Linux 8 vb..) PostgreSQL Kurulumu
# dnf install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
#sudo dnf -y module disable postgresql
#sudo dnf -y install postgresql13-server postgresql13 postgresql13-contrib
İndirilen rpm leri bir kontrol edelim;
# rpm -qa|grep postgres
postgresql-server-13.5-1.module_el8.5.0+1062+8eba5f44.x86_64
postgresql13-13.5-1PGDG.rhel8.x86_64
postgresql-13.5-1.module_el8.5.0+1062+8eba5f44.x86_64
postgresql13-libs-13.5-1PGDG.rhel8.x86_64
postgresql13-server-13.5-1PGDG.rhel8.x86_64
postgresql13-contrib-13.5-1PGDG.rhel8.x86_6
Postgres user için sudo yetkisi tanımlamalıyız.
# vi /etc/sudoers
## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
postgres ALL=(ALL) NOPASSWD: ALL
postgres user için bash_profile ayarlarımızı yapalım;
PGDATA=/postgres/13/data
export PGDATA
# If you want to customize your settings,
# Use the file below. This is not overridden
# by the RPMS.
[ -f /var/lib/pgsql/.pgsql_profile ] && source /var/lib/pgsql/.pgsql_profile
export PATH=/usr/pgsql-13/bin:$PATH
initdb ile kurulumu gerçekleştirelim
$ cd $PGDATA
$ initdb -D /postgres/13/data -k
Her iki node içinde aynı kurulumu gerçekleştiriyoruz.
İlk başta Primary olacak node için aşağıdaki düzenlemeleri yapıyoruz;
$ pg_ctl start
$ psql
create user bfmuser encrypted password 'Welcome1' superuser;
pg_hba ayarlarımızı yapalım;
hostssl replication bfmuser 192.168.5.132/32 scram-sha-256
hostssl replication bfmuser 192.168.5.133/32 scram-sha-256
--ssl istemiyor isek
host replication bfmuser 192.168.5.132/32 md5
host replication bfmuser 192.168.5.133/32 md5
postgresql.conf ayarları ve postgresql best practice konfigüreasyonları için. https://www.farukcevik.com.tr/postgresql-13-kurulumu/
BFM ve Komponentlerinin Kurulumu
Dört adet kurulum için dosyası gerekmekte.
- jdk-11.0.11_linux-x64_bin.rpm
- bfm-0.0.1-1.el8.noarch.rpm
- rpm -ivh minipg-0.0.1-1.el8.noarch.rpm
- bfm_setttings.tar.gz
Bu dosyaların yüklemesini yapıyoruz; root user ile her iki node içinde kurulum yapılmalıdır.
# rpm -ivh jdk-11.0.11_linux-x64_bin.rrr
# rpm -ivh bfm-0.0.1-1.el8.noarch.rpm
# rpm -ivh minipg-0.0.1-1.el8.noarch.rpm
Kurulum yapıldıktan sonra /etc/bfm altında BFM ve Minipg tüm konfigürasyon dosyaları burada oluşacaktır. Bu dosyaları düzenmesi için; ilgili dizin altında
# cd /etc/bfm/
# tar -xvf bfm_setttings.tar.gz
# cd /etc/bfm/bfmwatcher/
# rm -f bfm-1.3.13-SNAPSHOT.jar
# cd /etc/bfm/minipg/
# rm -f mini-pg-1.8.12-SNAPSHOT.jar
BFM ve Minipg Konfigürasyon dosyalarını düzenleyelim.
192.168.5.132 Ip li node1 makinesi için;
# vi /etc/bfm/bfmwatcher/application.properties
server.bfmList = 127.0.0.1
server.pguser = bfmuser
server.pgpassword = welcome1
watcher.cluster-port = 9994
watcher.cluster-pair = 192.168.5.133:9994
app.bfm-vip-enabled = true
# use only one of {availability,manual,performance,protection}
# or it will run in availability mode!
#server.masterip=
server.postgres_bin_path = /usr/pgsql-13/bin
server.postgres_data_path = /postgres/13/data
server.postgres_pgpass_path = /home/postgres
server.pglist=192.168.5.132:5432,192.168.5.133:5432
app.bfm-ssl-enabled = false
bfm.user-crypted = false
bfm.use-tls = false
minipg.use-tls = false
minipg.username = bfmuser
minipg.password = welcome1
Minipg için konfigürasyon
# vi /etc/bfm/minipg/application.properties
#minipg.postgres_bin_path=C:/Program Files/PostgreSQL/9.6/bin/
#minipg.postgres_data_path=D:/winPG_yedek/
#minipg.os=windows
minipg.postgres_bin_path = /usr/pgsql-13/bin/
minipg.pgctl_bin_path = /usr/pgsql-13/bin/
minipg.postgres_data_path = /postgres/13/data/
minipg.restore-command = restore_command = '/bin/true'
minipg.os = linux
minipg.version = @project.version@
minipg.postgres_pass_file_path = /var/lib/pgsql/.pgpass
minipg.pg-version = V12X
application.vip-interface = ens160:1
application.vip-ip = 192.168.5.140
application.vip-ip-netmask = 255.255.255.0
bfm.approval-key = test
minipg.port = 7779
bfm.rep_user = bfmuser
application.replication-user = bfmuser
minipg.use-tls = false
bfm.user-crypted = false
minipg.username = bfmuser
minipg.password = welcome1
192.168.5.133 Node2 için
vi /etc/bfm/bfmwatcher/application.properties
server.bfmList = 127.0.0.1
server.pguser = bfmuser
server.pgpassword = welcome1
watcher.cluster-port = 9994
watcher.cluster-pair = 192.168.5.132:9994
app.bfm-vip-enabled = true
# use only one of {availability,manual,performance,protection}
# or it will run in availability mode!
#server.masterip=
server.postgres_bin_path = /usr/pgsql-13/bin
server.postgres_data_path = /postgres/13/data
server.postgres_pgpass_path = /home/postgres
server.pglist=192.168.5.133:5432,192.168.5.132:5432
app.bfm-ssl-enabled = false
bfm.user-crypted = false
bfm.use-tls = false
minipg.use-tls = false
minipg.username = bfmuser
minipg.password = welcome1
minipg için
vi /etc/bfm/minipg/application.properties
#minipg.postgres_bin_path=C:/Program Files/PostgreSQL/9.6/bin/
#minipg.postgres_data_path=D:/winPG_yedek/
#minipg.os=windows
minipg.postgres_bin_path = /usr/pgsql-13/bin/
minipg.pgctl_bin_path = /usr/pgsql-13/bin/
minipg.postgres_data_path = /postgres/13/data/
minipg.restore-command = restore_command = '/bin/true'
minipg.os = linux
minipg.version = @project.version@
minipg.postgres_pass_file_path = /var/lib/pgsql/.pgpass
minipg.pg-version = V12X
application.vip-interface = ens160:1
application.vip-ip = 192.168.5.140
application.vip-ip-netmask = 255.255.255.0
bfm.approval-key = test
minipg.port = 7779
bfm.rep_user = bfmuser
application.replication-user = bfmuser
minipg.use-tls = false
bfm.user-crypted = false
minipg.username = bfmuser
minipg.password = welcome1
Buradaki /etc/bfm altındaki tüm dosyalar için sahiplik mutaka postgres userında olmalıdır;
chown postgres. -R /etc/bfm
.pgpass dosyasını hazırlayalım
$ vi /var/lib/pgsql/.pgpass
#hostname:port:database:username:password
*:5432:*:bfmuser:welcome1
.pgpass dosyasının permisson ları önemli onlar ayarlanmalıdır;
# chown postgres. /var/lib/pgsql/.pgpass
# chmod 0600 /var/lib/pgsql/.pgpass
BFM ayarları tamamlandı, bundan sonrası için pg_basebackup ile replica mızı oluşlturup bfm ve minipg yi çalıştırarak replica ve diğer kontrolleri bfm yönetimine bırakmak olacaktır.
Replica Oluşturma;
192.168.5.132 Master 192.168.5.133 Replica olacak şekilde ayarlar isek (Seçim bizim hangisi olduğu fark etmez). Replika olacak kısmın $PGDATA daki data kısmını tamamen temizliyoruz.
$ cd $PGDATA
$ /postgres/13/data
$ pg_ctl stop
$ rm -rf *
$ pg_basebackup -h 192.168.5.132 -p 5432 -U bfmuser -D /postgres/13/data -P -v -R -Xs
$ pg_ctl start
Replika kuruldu artık BFM ve Minipg yi start ve enable edebiliriz ve yönetimi BFM e devredebiliriz.
BFM Start ve Enable Sırasıyla önce master da sonra slave de
$ sudo systemctl start bfm
$ sudo systemctl start minipg
$ sudo systemctl enable bfm
$ sudo systemctl enable minipg
Master sunucuda VIP IP yi ayağa kaldıralım.
sudo ifconfig ens160:1 192.168.5.140/24
BFM ve Minipg Çalışması Kontrolleri
BFM yanlızca bir nodda aktif olarak çalışacaktır, log dosyası –> /etc/bfm/bfmwatcher/bfm.log
tail -1000f /etc/bfm/bfmwatcher/bfm.log
-----Cluster Healthcheck Started-----
Status of 192.168.5.132:5432 is MASTER
["pg_ctl: server is running (PID: 10055)","/usr/pgsql-13/bin/postgres"]
Status of 192.168.5.133:5432 is SLAVE
["pg_ctl: server is running (PID: 7265)","/usr/pgsql-13/bin/postgres"]
Cluster has a master node
-----Cluster Status is HEALTHY-----
-----Cluster Healthcheck Finished-----
status of bfm pair is :Passive
this is the active bfm pair
-----Cluster Healthcheck Started-----
Status of 192.168.5.132:5432 is MASTER
["pg_ctl: server is running (PID: 10055)","/usr/pgsql-13/bin/postgres"]
Status of 192.168.5.133:5432 is SLAVE
["pg_ctl: server is running (PID: 7265)","/usr/pgsql-13/bin/postgres"]
Cluster has a master node
-----Cluster Status is HEALTHY-----
-----Cluster Healthcheck Finished-----
minipg için log dosyası –> /etc/bfm/minipg/minipg.log
tail -1000f /etc/bfm/minipg/minipg.log
EXECUTING THIS:/usr/pgsql-13/bin/pg_ctl status -D/postgres/13/data/
waiting for .... /usr/pgsql-13/bin/pg_ctl status -D/postgres/13/data/ to execute......
pg_ctl: server is running (PID: 10055)
/usr/pgsql-13/bin/postgres
EXECUTING THIS:/usr/pgsql-13/bin/pg_ctl status -D/postgres/13/data/
waiting for .... /usr/pgsql-13/bin/pg_ctl status -D/postgres/13/data/ to execute......
pg_ctl: server is running (PID: 10055)
/usr/pgsql-13/bin/postgres
Failover Test : Master sunucumuz şu an 192.168.5.132 dir burada postgresi kapatalım, bakalım tüm işleri BFM yapacakmı?
[postgres@bfmnd1 ~]$ pg_ctl stop
waiting for server to shut down.... done
server stopped
Bu sırada bfm logu takip ettiğimizde
-----Cluster Healthcheck Started-----
Unable to get replication status of 192.168.5.132:5432
Unable get master status of 192.168.5.132:5432
Status of 192.168.5.132:5432 is INACCESSIBLE
[]
Status of 192.168.5.133:5432 is SLAVE
["pg_ctl: server is running (PID: 7265)","/usr/pgsql-13/bin/postgres"]
Cluster has no master
master server is not healthy
remaining ignorance count is: 1
-----Cluster Status is NOT_HEALTHY-----
-----Cluster Healthcheck Finished-----
Unable to find master server for cluster
this is the active bfm pair
-----Cluster Healthcheck Started-----
Unable to get replication status of 192.168.5.132:5432
Unable get master status of 192.168.5.132:5432
Status of 192.168.5.132:5432 is INACCESSIBLE
status of bfm pair is :Passive
[]
Status of 192.168.5.133:5432 is SLAVE
["pg_ctl: server is running (PID: 7265)","/usr/pgsql-13/bin/postgres"]
Cluster has no master
Failover Started
New master server is 192.168.5.133:5432
vip down sent to 192.168.5.132:5432
200
promote sent to 192.168.5.133:5432
200
vip up sent to 192.168.5.133:5432
200
rewind sent to 192.168.5.132:5432 for master 192.168.5.133:5432
200
Failover Finished
-----Cluster Status is HEALTHY-----
-----Cluster Healthcheck Finished-----
Unable to find master server for cluster
this is the active bfm pair
-----Cluster Healthcheck Started-----
Status of 192.168.5.132:5432 is SLAVE
["pg_ctl: server is running (PID: 31154)","/usr/pgsql-13/bin/postgres \"-D\" \"/postgres/13/data\""]
Status of 192.168.5.133:5432 is MASTER
["pg_ctl: server is running (PID: 7265)","/usr/pgsql-13/bin/postgres"]
Cluster has a master node
-----Cluster Status is HEALTHY-----
133 artık master diyor 133 e bakalım; VIP IP Check
[postgres@bfmnd2 data]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:72:ec:93 brd ff:ff:ff:ff:ff:ff
inet 192.168.5.133/24 brd 192.168.5.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet 192.168.5.140/24 brd 192.168.5.255 scope global secondary ens160:1
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe72:ec93/64 scope link noprefixroute
valid_lft forever preferred_lft forever
Kontrolleri yapalım
- VIP Ip taşındımı
- read-write open mı?
- Eski master Slave oldumu?
Aşağıda sırasıyla bu üçününde başarılı bir şekilde BFM tarafından yapıldığını görüyoruz.
[postgres@bfmnd2 data]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:72:ec:93 brd ff:ff:ff:ff:ff:ff
inet 192.168.5.133/24 brd 192.168.5.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet 192.168.5.140/24 brd 192.168.5.255 scope global secondary ens160:1
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe72:ec93/64 scope link noprefixroute
valid_lft forever preferred_lft forever
$ psql
psql (13.6)
Type "help" for help.
postgres=# select * from pg_is_in_recovery();
pg_is_in_recovery
-------------------
f
(1 row)
postgres=# select * from pg_stat_replication;
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn
| write_lag | flush_lag | replay_lag | sync_priority | sync_state | reply_time
------+----------+---------+-------------------+---------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------
+-----------+-----------+------------+---------------+------------+-------------------------------
7865 | 16384 | bfmuser | bfmnd1.frkcvk.com | 192.168.5.132 | | 41830 | 2022-08-04 11:33:19.969388+03 | | streaming | 0/170003C0 | 0/170003C0 | 0/170003C0 | 0/170003C0
| | | | 0 | async | 2022-08-04 11:37:21.020979+03
(1 row)
BFM ile ilgili olarak ssl, özelliği birden fazla slave oluşturma ve bunlar içerisinde seçilen slave nodlara otomatik failover ile switcover özelliğinin kapatılması, sadece seçilen node lar üzerine failover yapılması, Farklı Subnet teki sunucular, uzak lokasyonlar için witness server lar ve özel VIP IP yapılarının kullanılması gibi özellikleri mevcut ancak yazı zaten hali hazırda fazlasıyla uzun olduğu için bu konuları ayrıca başka bir yazıda ele alacağım.
Bir yanıt yazın