PostgreSQL adalah relational database management system (RDBMS) yang kuat, kaya fitur, open-source, dan telah dikembangkan sejak tahun 1996. Postgres menawarkan berbagai cara pengarsipan dan replikasi data, salah satunya adalah streaming replication.

Dalam mode streaming replication, instance primer (master) menangani database aktif utama dan menjalankan operasi. Sedangkan instance sekunder (slave) menyalin semua perubahan dari instance primer, mempertahankan salinan identik dari database aktif. Server sekunder juga dapat menerima permintaan read-only. Jika instance primer gagal, server sekunder dapat menggantikan instance primer dan berubah dari mode standby berubah sebagai master baru (ini disebut metode failover).

PostgreSQL replication (Replikasi PostgreSQL) biasanya bergantung pada write-ahead logging (WAL), proses logging data berubah sebelum menulisnya ke disk. WAL records ini kemudian disalin ke node kedua sebagai file (pengiriman log berbasis file), atau langsung dialirkan antar node (streaming replikasi). Dalam kebanyakan kasus, yang terakhir mengurangi delay untuk perubahan pada master node yang akan diterima oleh node siaga.

Masalah dengan menggunakan replikasi streaming tanpa pengiriman log berbasis file adalah bahwa server sekunder mungkin kehilangan beberapa WAL records jika primer dumping terlalu cepat. Sejumlah parameter konfigurasi dapat mengurangi risiko ini, tetapi seringkali disertai dengan biaya penyimpanan yang tidak perlu. Solusinya adalah replication slots (replikasi slot), fitur yang disediakan oleh Postgres yang memastikan server primer hanya membuang WAL records setelah diterima oleh node standby.

Kami akan menyiapkan streaming replikasi dengan replikasi slot pada dua node 10 Debian.

Persyaratan

  • Dua instance Debian 10 yang identik.
  • Memiliki akses root ke kedua instance.
  • environment variable $EDITOR harus diset pada kedua instance.

Langkah 1: Menginstal PostgreSQL

Perbarui paket sistem operasi Anda di kedua node. Ini adalah langkah pertama yang penting karena memastikan Anda memiliki pembaruan terbaru dan perbaikan keamanan untuk paket perangkat lunak default sistem operasi Anda:

sudo apt update && sudo apt upgrade -y

reboot kedua node setelah selesai melakukan proses update untuk meminimalisir terjadinya kesalahan.

Install Postgres di kedua node dan pastikan PostgreSQL diaktifkan dan berjalan:

apt install -y postgresql
systemctl enable --now [email protected]

NOTE: Saat update PostgreSQL, dahulukan server standy, ini adalah opsi yang lebih aman sesuai dengan dokumentasi PostgreSQL.

Langkah 2: Konfigurasi Awal

Secara default, PostgreSQL hanya listens pada antarmuka loopback dan tidak dapat diakses secara eksternal. Ubah listen address di kedua node dengan mengedit postgresql.conf:

$EDITOR /etc/postgresql/11/main/postgresql.conf

Temukan baris berikut:

#listen_addresses = 'localhost'

Ubah ke:

listen_addresses = 'alamat_ip_node,127.0.0.1'

Jika kedua node berbagi jaringan lokal yang sama, Anda dapat menggunakan private addresses untuk node_ip_address, meskipun Postgres tidak dapat diakses internet. Kalau tidak, gunakan public addresses.

Simpan perubahan, lalu restart kedua instance:

systemctl restart [email protected]

Langkah 3: Konfigurasi Server Master

Langkah ini hanya berkaitan dengan server primer/master.

Buka terminal Postgres:

sudo -u postgres psql

Node standby akan menggunakan user untuk terhubung ke master. Buat user untuk terkoneksi dengan server master:

postgres=# CREATE ROLE replicator LOGIN REPLICATION ENCRYPTED PASSWORD 'password_untuk_replicator';

Kemudian buat slot replikasi dan keluar:

postgres=# SELECT * FROM pg_create_physical_replication_slot('replicator');
postgres=# \q

Demi kesederhanaan, role dan slot replikasi keduanya bernama “replicator“, meskipun mereka tidak harus identik.

Selanjutnya, buat entri di pg_hba.conf untuk memungkinkan user replicator terhubung dari instance standby ke instance master. Buka:

$EDITOR /etc/postgresql/11/main/pg_hba.conf

Tambahkan baris berikut pada bagian akhir:

host	replication	replicator	standby_ip_address/32		md5

Restart instance master:

systemctl restart [email protected]

Langkah 4: Konfigurasi Server Slave

Perintah dalam langkah ini harus dijalankan pada server sekunder / slave.

Pertama, hentikan Postgres pada node sekunder:

systemctl stop [email protected]

Backup direktori data lama:

mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.bak

Gunakan perintah berikut untuk mengkloning direktori data master ke slave:

pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator

Anda akan dimintai kata sandi. Masukkan kata sandi yang Anda pilih untuk user replicator ketika dibuat di server master. Setelah transfer selesai, berikan kepemilikan direktori data kepada user postgres:

chown -R postgres:postgres /var/lib/postgresql/11/main

Langkah 5: Konfigurasi Standby

Langkah ini hanya berkaitan dengan server sekunder/slave.

Aktifkan mode hot standby di postgresql.conf:

$EDITOR /etc/postgresql/11/main/postgresql.conf

Temukan dan batalkan komentar pada baris berikut:

#hot_standby = on

Buat file recovery.conf di direktori data Postgres:

$EDITOR /var/lib/postgresql/11/main/recovery.conf

Aktifkan mode standby :

standby_mode = 'on'

Set parameter koneksi replikasi menggunakan kredensial yang dibuat ketika di server master:

primary_conninfo = 'host=master_ip_address port=5432 user=replicator password=password_untuk_replicator'

Tetapkan nama replikasi slot yang Anda buat pada master:

primary_slot_name = 'replicator'

Set path ke file failover trigger :

trigger_file = '/var/lib/postgresql/11/main/failover.trigger'

Jika parameter trigger_file diatur, Postgres akan keluar dari standby mode dan memulai operasi normal sebagai server primer (master). Parameter ini tidak diperlukan.

Setelah membuat recovery.conf, berikan kepemilikan kepada user postgres:

chown postgres:postgres /var/lib/postgresql/11/main/recovery.conf

Anda sekarang dapat memulai Postgres:

systemctl start [email protected]

Sekarang dalam mode standby dan akan mereplikasi setiap ada transaksi baru.

Testing Replikasi dan Failover PostgreSQL

Pengujian Replikasi PostgreSQL

Untuk menguji replikasi, lakukan tindakan write data apa pun pada master. Misalnya, buat database baru di master:

sudo -u postgres psql -c "CREATE DATABASE replitest"

Tunggu beberapa detik lalu buat list database pada server slave:

sudo -u postgres psql -c "\l"

Anda akan melihat bahwa database “replitest” direplikasi oleh standby server :

List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 replitest | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(4 rows)

Testing Metode Failover

Note: Menguji failover seperti yang ditunjukkan di sini akan memerlukan pengaturan ulang standby server setelah failover dijalankan.

Karena Postgres dalam mode standby, Anda seharusnya tidak dapat melakukan operasi write pada node sekunder sebelum failover terjadi. Misalnya, jalankan perintah berikut:

sudo -u postgres psql -c "CREATE DATABASE test"

Perintah akan gagal:

ERROR:  cannot execute CREATE DATABASE in a read-only transaction

Untuk memberi sinyal failover, buat file kosong dengan perintah touch yang berfungsi sebagai pemicu seperti yang telah ditentukan dalam recovery.conf

touch /var/lib/postgresql/11/main/failover.trigger

Tunggu beberapa detik, lalu coba lakukan operasi write. Sebagai contoh:

sudo -u postgres psql -c "CREATE DATABASE test2"

Karena Postgres tidak lagi beroperasi sebagai standby server, operasi akan berhasil. Postgres juga akan mengganti nama file recovery.conf Anda menjadi recovery.done, dan akan menghapus file trigger.

Untuk mengembalikan instance menjadi mode standby, hentikan Postgres pada node sekunder (sebelumnya):

systemctl stop [email protected]

Reset direktori data:

mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.2.bak
pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator
chown -R postgres:postgres /var/lib/postgresql/11/main

Dan buat kembali recovery.conf:

cp /var/lib/postgresql/11/main.2.bak/recovery.done /var/lib/postgresql/11/main/recovery.conf

Terakhir, restart Postgres:

systemctl start [email protected]

instance sekunder sekarang kembali ke mode standby. Anda mungkin ingin menguji ulang konfigurasi replikasi pada titik ini.

Hapus semua databases yang tidak perlu pada master node, misalnya:

sudo -u postgres psql
postgres=# DROP DATABASE replitest;

Dan hapus direktori data lama pada node standby Anda:

rm /var/lib/postgresql/11/main.bak -r
rm /var/lib/postgresql/11/main.2.bak -r