Yay PostgreSQL 11 baru saja keluar bulan lalu (lihat di sini untuk diskusi HN). Yuk kita coba mengkonfigurasi replikasi di PostgreSQL 11.
Replikasi di PostgreSQL
Replikasi di PostgreSQL didasarkan pada teknologi Write Ahead Log (WAL). Fungsi WAL sangat simpel. Seperti namanya, WAL menjadikan PostgreSQL untuk menulis log sebelum setiap perubahan yang terjadi. Perubahan data tidak akan dilakukan sebelum WAL berhasil disimpan ke storage. Log ini berisi perubahan yang dilakukan kepada PostgreSQL. Dengan demikian integritas data di PostgreSQL dapat terjamin. Apabila server crash sebelum perubahan data dilakukan, PostgreSQL dapat membaca WAL terakhir dan menjalankannya lagi. Selain itu, apabila kita memiliki WAL yang lengkap, kita dapat menjalankan ulang seluruh WAL dari awal sampai akhir untuk mendapatkan state terakhir. Sehingga WAL juga dapat digunakan untuk mekanisme backup juga.
Fungsi WAL tidak hanya itu saja. Bagaimana jika kita mengirim WAL dari server PostgreSQL A ke server B, dan server B langsung menjalankan WAL ketika menerimanya. Yap, server B akan memiliki state yang sama dengan server A! Inilah yang disebut sebagai streaming replication pada PostgreSQL.
Memang tidak ketika perubahan terjadi di server A, server B seketika itu juga memiliki state yang sama dengan server A. Terdapat delay selama beberapa saat sebelum state server B sama dengan server A. Hal ini dikarenakan diperlukan waktu untuk mengirimkan WAL dari server A ke server B, dan server B juga memerlukan waktu untuk menjalankan WAL yang diterima. Akan tetapi kita bisa menjamin bahwa suatu saat nanti, server B akan memiliki state yang sama dengan server A. Hal ini disebut sebagai eventually consistent.
Akan tetapi bagaimana jika terdapat WAL yang hilang di network, sehingga server B tidak akan pernah menerimanya. Jika ini terjadi maka server B tidak akan pernah bisa memiliki state yang sama dengan server A. Untuk mengatasi hal ini, PostgreSQL memiliki fitur untuk menjalankan WAL dari sumber lain. Akan tetapi WAL yang ditulis di server A harus disimpan pada storage yang dapat diakses dari server B.
Konfigurasi replikasi
Kita akan menggunakan PostgreSQL versi 11 pada server Ubuntu 18.04. Replikasi yang kita buat akan memiliki skema seperti ini:
Kita akan membutuhkan 4 server. Diasumsikan bahwa untuk server berikut dapat melakukan passwordless SSH ke server lain (cek di sini untuk bagaimana mengkonfigurasi passwordless SSH):
|
|
primary
merupakan server utama yang menjalankan perubahan data dari client. Sedangkan slave1
dan slave2
merupakan server yang menerima WAL dari primary
. Sedangkan wal_storage
merupaan server yang menyimpan WAL yang ditulis dari server primary
, slave1
dan slave2
.
Install PostgreSQL 11
Ikuti langkan di sini untuk menginstall PostgreSQL 11 di server
primary
,slave1
danslave2
.Membuat user replikasi
Server slave harus terhubung ke server
primary
untuk mendapatkan akses ke WAL serverprimary
. Kita akan menggunakan user khusus untuk ini. Untuk membuatnya, pada serverprimary
,slave1
danslave2
masuk ke userpostgres
lalu jalankan perintah berikut:1
psql -c "create user replicator with replication login;"
Opsi
replication
menandakan bahwa user yang dibuat merupakan user khusus yang digunakan untuk replikasi dan opsilogin
memungkinkan user ini untuk melakukan login dari server lain.Konfigurasi
pg_hba.conf
PostgreSQL memiliki file
pg_hba.conf
yang befungsi untuk mengatur koneksi yang diijinkan masuk. Agar replikasi dapat berjalan, makaslave1
danslave2
harus dapat mengaksesprimary
dengan menggunakan userreplicator
. Untuk itu tambahkan baris berikut pada/etc/postgresql/11/main/pg_hba.conf
1 2 3
# ganti NETWORK dengan CIDR yang mencakup server primary, slave1 dan slave2 # misal 10.11.12.0/24 host replication replicator NETWORK trust
Baris tersebut artinya koneksi yang masuk lewat TCP/IP, yang berasal dari IP yang termasuk CIDR yang didefinisikasn di
NETWORK
, yang menggunakan userreplicator
untuk keperluanreplication
, akan diijinkan.Lakukan ini di server
primary
,slave1
danslave2
.Konfigurasi PostgreSQL
Buka file
/etc/postgresql/11/main/postgresql.conf
dan sesuaikan/tambahkan konfigurasi untuk:1 2 3 4
listen_addresses = '*' wal_level = 'replica' # diperlukan agar data yang ditulis di WAL dapat digunakan untuk keperluan replikasi max_wal_senders = 3 # jumlah proses pengiriman WAL yang diijinkan, paling tidak harus sama dengan jumlah server slave wal_keep_segments = 500 # jumlah file WAL yang disimpan
Lakukan ini di server
primary
,slave1
danslave2
. Lalu restart service postgres agar PostgreSQL membaca perubahan konfigurasi.Konfigurasi penyimpanan WAL
Tambahkan baris berikut di
/etc/postgresql/11/main/postgresql.conf
1 2
archive_mode = 'on' archive_command = 'rsync -az %p $USER@$IP_WAL_STORAGE:~/wals/'
Kita menggunakan
archive_command
untuk menyimpan file WAL yang dibuat oleh PostgreSQL di serverwal_storage
.archive_command
akan dijalankan untuk setiap file WAL yang dibuat oleh PostgreSQL. Kita menggunakanrsync
untuk menyimpan file WAL. Kenaparsync
? Karena kita memiliki 3 server PostgreSQL yang menghasilkan WAL yang sama maka kita harus mengecek apakah file WAL telah disimpan ke storage. Dengan menggunakanrsync
, kita bisa menghilangkan proses pengecekan tersebut. Karenarsync
tidak akan melakukan apa apa apabila file WAL telah disimpan.Lakukan ini di server
primary
,slave1
danslave2
. Lalu restart service postgres agar PostgreSQL membaca perubahan konfigurasi.Copy state
primary
ke slaveJalankan perintah berikut di server
slave1
danslave2
1 2 3 4
systemctl stop postgresql rm -rf /var/lib/postgresql/11/main pg_basebackup --pgdata=/var/lib/postgresql/11/main --write-recovery-conf --progress --verbose --host=$IP_PRIMARY --username=replicator chown -R postgres:postgres /var/lib/postgresql/11/main
Perintah di atas akan membuat ulang data PostgreSQL agar memiliki state yang sama dengan
primary
. Selain itu juga mengkonfigurasi streaming replication pada file/var/lib/postgresql/11/main/recovery.conf
yang berisi:1 2
standby_mode = 'on' primary_conninfo = 'user=replicator passfile=''/root/.pgpass'' host=IP_PRIMARY port=5432 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
Tambahkan baris berikut pada
/var/lib/postgresql/11/main/recovery.conf
:1
restore_command = 'rsync -az $USER@$IP_WAL_STORAGE:~/wals/%f %p'
Dengan konfigurasi
recovery.conf
seperti di atas, server akan terus menjalankan WAL yang didapat dari serverprimary
. Selain itu, apabila file WAL tidak didapatkan dari streaming replication, server akan menjalankan perintah yang terdapat padarestore_command
untuk mendapatkan file WAL tersebut.Selanjutnya jalankan service postgres pada server
slave1
danslave2
. Jika konfigurasi benar, akan muncul prosespostgres: 11/main: walsender
pada serverprimary
untuk setiap slave yang terhubung.1 2
17659 ? Ss 0:00 postgres: 11/main: walsender replicator IP_SLAVE_1(51648) streaming 0/7000060 17660 ? Ss 0:00 postgres: 11/main: walsender replicator IP_SLAVE_2(60446) streaming 0/7000060
Tes replikasi
Semua perubahan yang terjadi pada server primary
akan diikuti oleh server slave juga. Untuk mencobanya dapat dilakukan dengan membuat database / tabel pada server primary
. Setelah beberapa saat, database / tabel tersebut juga akan muncul pada server slave.
Selain itu, status replikasi dapat juga dilakukan dengan melakukan query berikut di server primary
|
|
Demikianlah fitur replikasi bawaan PostgreSQL. Apabila diperhatikan, replikasi hanya berjalan satu arah. Perubahan dari server primary
akan direplikasi ke server slave, akan tetapi tidak sebaliknya. Oleh karena itu semua query yang melakukan perubahan ke database harus diarahkan ke server primary
dan kapasitas perubahan database dibatasi oleh spesifikasi server primary
. Akan tetapi, query yang membaca data dari database dapat ditujukan ke salah satu server slave. Apabila kebutuhan kapasitas perubahan database sangat besar dan sebuah server primary
tidak dapat mengatasinya, maka skenario ini tidak dapat digunakan. Terdapat beberapa project lain yang memungkinkan menggunakan skenario multi-master pada PostgreSQL, misalnya Cockroachdb dan Citus.