Ini adalah bagian kedua dari blog “A Guide to Pgpool for PostgreSQL”. Bagian pertama yang meliputi load balancing, session pooling, dalam cache memori dan instalasi dapat ditemukan di sini.
Banyak pengguna melihat ke pgpool khusus untuk fitur Ketersediaan Tinggi, dan memiliki banyak hal untuk ditawarkan. Ada beberapa instruksi yang cukup banyak untuk pgpool HA di web (mis. yang lebih panjang dan yang lebih pendek), jadi tidak masuk akal untuk mengulanginya. Kami juga tidak ingin memberikan set nilai konfigurasi buta lainnya. Sebaliknya saya menyarankan untuk bermain melawan aturan dan mencoba melakukannya dengan cara yang salah, jadi kita akan melihat beberapa perilaku yang menarik. Salah satu fitur teratas yang diharapkan (setidaknya ada di bagian atas halaman) adalah kemampuan untuk mengenali kegunaan dari mantan master "mati" dan menggunakannya kembali dengan pg_rewind. Ini dapat menghemat waktu berjam-jam untuk mengembalikan standby baru dengan data besar (karena kami melewatkan rsync atau pg_basebackup, yang secara efektif menyalin SEMUA file dari master baru). Sebenarnya, pg_rewind dimaksudkan untuk failover yang direncanakan (selama peningkatan atau migrasi ke perangkat keras baru). Tapi kita telah melihat ketika itu sangat membantu dengan shutdown yang tidak terencana namun tetap anggun dan failover otomatis - misalnya, ClusterControl memanfaatkannya saat melakukan failover otomatis dari slave replikasi. Mari kita asumsikan kita memiliki kasus:kita membutuhkan master (apa pun) agar dapat diakses sebanyak mungkin. Jika karena alasan tertentu (kegagalan jaringan, koneksi maksimal terlampaui atau "kegagalan" lainnya yang melarang sesi baru untuk memulai) kami tidak lagi dapat menggunakan master untuk operasi RW, kami memiliki cluster failover yang dikonfigurasi, dengan budak yang dapat menerima koneksi. Kami kemudian dapat mempromosikan salah satu budak dan gagal melakukannya.
Pertama mari kita asumsikan kita memiliki tiga node:
- 10.1.10.124:5400 dengan /pg/10/m (pgpool juga berputar di sini)
- 10.1.10.147:5401 dengan /pg/10/m2
- 10.1.10.124:5402 dengan /hal/10/s2
Itu secara efektif adalah node yang sama seperti di bagian satu, tetapi node failover dipindahkan ke host yang berbeda dan $PGDATA. Saya melakukannya untuk memastikan saya tidak salah ketik atau lupa beberapa kutipan tambahan dalam perintah ssh jarak jauh. Juga info debugging akan terlihat lebih sederhana karena alamat ip berbeda. Akhirnya saya tidak yakin saya akan dapat membuat kasus penggunaan yang tidak didukung ini berfungsi, jadi saya harus melihatnya dengan mata kepala sendiri.
Kegagalan
Pertama kita atur failover_command dan jalankan pgpool reload dan coba failover. Di sini dan selanjutnya, saya akan menggemakan beberapa info ke /tmp/d di server pgpool, jadi saya bisa mengikuti -f /tmp/d untuk melihat alurnya.
[email protected]:~$ grep failover_command /etc/pgpool2/pgpool.conf
failover_command = 'bash /pg/10/fo.sh %D %H %R'
[email protected]:~$ cat /pg/10/fo.sh
rem_cmd="pg_ctl -D $3 promote"
cmd="ssh -T [email protected]$2 $rem_cmd"
echo "$(date) $cmd" >>/tmp/d
$cmd &>>/tmp/d
NB:Apakah Anda memiliki $PATH yang disetel di .bashrc pada host jarak jauh?..
Mari kita hentikan master (saya tahu ini bukan bagaimana bencana terjadi, Anda mengharapkan setidaknya beberapa monyet besar atau robot bersinar merah untuk menghancurkan server dengan palu besar, atau setidaknya hard disk yang membosankan mati, tapi saya menggunakan ini anggun varian untuk mendemonstrasikan kemungkinan penggunaan pg_rewind, jadi di sini failover akan menjadi hasil dari kesalahan manusia atau kegagalan jaringan setengah detik selama health_check_period), jadi:
/usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m stop
2018-04-18 13:53:55.469 IST [27433] LOG: received fast shutdown request
waiting for server to shut down....2018-04-18 13:53:55.478 IST [27433] LOG: aborting any active transactions
2018-04-18 13:53:55.479 IST [28855] postgres t FATAL: terminating connection due to administrator command
2018-04-18 13:53:55.483 IST [27433] LOG: worker process: logical replication launcher (PID 27440) exited with exit code 1
2018-04-18 13:53:55.484 IST [27435] LOG: shutting down
2018-04-18 13:53:55.521 IST [27433] LOG: database system is shut down
done
server stopped
Sekarang memeriksa output perintah failover:
[email protected]:~$ cat /tmp/d
Wed Apr 18 13:54:05 IST 2018 ssh -T [email protected]
pg_ctl -D /pg/10/f promote
waiting for server to promote.... done
server promoted
Dan memeriksa setelah beberapa saat:
t=# select nid,port,st, role from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
nid | port | st | role
-----+------+------+---------
0 | 5400 | down | standby
1 | 5401 | up | primary
2 | 5402 | up | standby
(3 rows)
Kami juga melihat di log cluster ex-failover:
2018-04-13 14:26:20.823 IST [20713] LOG: received promote request
2018-04-13 14:26:20.823 IST [20713] LOG: redo done at 0/951EC20
2018-04-13 14:26:20.823 IST [20713] LOG: last completed transaction was at log time 2018-04-13 10:41:54.355274+01
2018-04-13 14:26:20.872 IST [20713] LOG: selected new timeline ID: 2
2018-04-13 14:26:20.966 IST [20713] LOG: archive recovery complete
2018-04-13 14:26:20.998 IST [20712] LOG: database system is ready to accept connections
Memeriksa replikasi:
[email protected]:~$ psql -p 5401 t -c "select now() into test"
SELECT 1
[email protected]:~$ psql -p 5402 t -c "select * from test"
now
-------------------------------
2018-04-13 14:33:19.569245+01
(1 row)
Budak /pg/10/s2:5402 beralih ke timeline baru berkat recovery_target_timeline =terbaru di recovery.conf, jadi kami baik-baik saja. Kita tidak perlu menyesuaikan recovery.conf untuk menunjuk ke master baru, karena itu menunjuk ke ip dan port pgpool dan mereka tetap sama tidak peduli siapa yang melakukan peran master utama.
Memeriksa penyeimbangan beban:
[email protected]:~$ (for i in $(seq 1 9); do psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1" -XAt; done) | sort| uniq -c
6 5401
3 5402
Bagus. Aplikasi di belakang pgpool akan melihat pemadaman kedua dan terus bekerja.
Menggunakan kembali mantan master
Sekarang kita dapat mengubah ex-master menjadi failover standby dan mengembalikannya (tanpa menambahkan node baru ke pgpool, karena sudah ada di sana). Jika Anda tidak mengaktifkan wal_log_hints atau checksum data (perbedaan menyeluruh antara opsi ini ada di sini), Anda harus membuat ulang cluster di ex-master untuk mengikuti timeline baru:
[email protected]:~$ rm -fr /pg/10/m
[email protected]:~$ pg_basebackup -h localhost -p 5401 -D /pg/10/m/
Tapi jangan terburu-buru menjalankan pernyataan di atas! Jika Anda berhati-hati dengan wal_log_hints (memerlukan restart), Anda dapat mencoba menggunakan pg_rewind untuk lebih cepat beralih dari mantan master ke budak baru.
Jadi ATM kami memiliki mantan master offline, master baru dengan timeline berikutnya dimulai. Jika mantan master offline karena kegagalan jaringan sementara dan kembali lagi, kita harus mematikannya terlebih dahulu. Dalam kasus di atas, kami tahu ini sedang down, jadi kami hanya dapat mencoba memutar ulang:
[email protected]:~$ pg_rewind -D /pg/10/m2 --source-server="port=5401 host=10.1.10.147"
servers diverged at WAL location 0/40605C0 on timeline 2
rewinding from last common checkpoint at 0/4060550 on timeline 2
Done!
Dan lagi:
[email protected]:~$ pg_ctl -D /pg/10/m2 start
server started
...blah blah
[email protected]:~$ 2018-04-16 12:08:50.303 IST [24699] LOG: started streaming WAL from primary at 0/B000000 on timeline 2
t=# select nid,port,st,role from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
nid | port | st | role
-----+------+------+---------
0 | 5400 | down | standby
1 | 5401 | up | primary
2 | 5402 | up | standby
(3 rows)
Operasi duh! Terlepas dari kenyataan bahwa cluster di port 5400 sedang online dan mengikuti timeline baru, kita perlu memberi tahu pgpool untuk mengenalinya:
[email protected]:~$ pcp_attach_node -w -h 127.0.0.1 -U vao -n 0
pcp_attach_node -- Command Successful
Sekarang ketiganya sudah aktif (dan pgpool mengetahuinya) dan sinkron:
[email protected]:~$ sql="select ts.i::timestamp(0), current_setting('data_directory'),case when pg_is_in_recovery() then 'recovering' else 'mastering' end stream from ts order by ts desc"
[email protected]:~$ psql -h 10.1.10.147 -p 5401 t -c "$sql";
i | current_setting | stream
---------------------+-----------------+-----------
2018-04-30 14:34:36 | /pg/10/m2 | mastering
(1 row)
[email protected]:~$ psql -h 10.1.10.124 -p 5402 t -c "$sql";
i | current_setting | stream
---------------------+-----------------+------------
2018-04-30 14:34:36 | /pg/10/s2 | recovering
(1 row)
[email protected]:~$ psql -h 10.1.10.124 -p 5400 t -c "$sql";
i | current_setting | stream
---------------------+-----------------+------------
2018-04-30 14:34:36 | /pg/10/m | recovering
(1 row)
Sekarang saya akan mencoba menggunakan recovery_1st_stage_command untuk menggunakan kembali mantan master:
[email protected]:~# grep 1st /etc/pgpool2/pgpool.conf
recovery_1st_stage_command = 'or_1st.sh'
Tetapi recovery_1st_stage_command tidak menawarkan argumen yang diperlukan untuk pg_rewind, yang dapat saya lihat jika saya tambahkan ke recovery_1st_stage_command:
echo "online recovery started on $(hostname) $(date --iso-8601) $0 $1 $2 $3 $4"; exit 1;
Keluaran:
online recovery started on u2 2018-04-30 /pg/10/m2/or_1st.sh /pg/10/m2 10.1.10.124 /pg/10/m 5401
Yah - menggunakan pg_rewind hanya dalam daftar yang harus dilakukan - apa yang saya harapkan?.. Jadi saya perlu melakukan beberapa hack monyet untuk mendapatkan master ip dan port (ingat itu akan terus berubah setelah failover).
Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh WhitepaperPeretasan monyet
Jadi saya memiliki sesuatu seperti ini di recovery_1st_stage_command:
[email protected]:~# cat /pg/10/or_1st.sh
pgpool_host=10.1.10.124
pgpool_port=5433
echo "online recovery started on $(hostname) $(date --iso-8601) $0 $1 $2 $3 $4" | ssh -T $pgpool_host "cat >> /tmp/d"
master_port=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select port from dblink('host=$pgpool_host port=$pgpool_port','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int) where role='primary'")
master_host=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select hostname from dblink('host=$pgpool_host port=$pgpool_port','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int) where role='primary'")
failover_host=$(psql -XAt -h $pgpool_host -p $pgpool_port t -c "select hostname from dblink('host=$pgpool_host port=$pgpool_port','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int) where role!='primary' order by port limit 1")
src='"port=$master_port host=$master_host"'
rem_cmd="'pg_rewind -D $3 --source-server=\"port=$master_port host=$master_host\"'"
cmd="ssh -T $failover_host $rem_cmd"
echo $cmd | ssh -T $pgpool_host "cat >> /tmp/d"
$cmd
tmp=/tmp/rec_file_tmp
cat > $tmp <<EOF
standby_mode = 'on'
primary_conninfo = 'host=$master_host port=$master_port user=postgres'
trigger_file = '/tmp/tg_file'
recovery_target_timeline = latest
EOF
scp $tmp $failover_host:$3/recovery.conf
rem_cmd="pg_ctl -D $3 start"
cmd="ssh -T $failover_host $rem_cmd"
echo $cmd | ssh -T $pgpool_host "cat >> /tmp/d"
$cmd
echo "OR finished $(date --iso-8601)" | ssh -T $pgpool_host "cat >> /tmp/d"
exit 0;
Sekarang berantakan! Nah - jika Anda memutuskan untuk menggunakan fitur yang tidak ada - persiapkan - itu akan terlihat buruk, bekerja lebih buruk dan Anda akan secara permanen merasa malu dengan apa yang Anda lakukan. Jadi langkah demi langkah:
- Saya memerlukan IP dan port pgpool untuk menghubungkannya dari jarak jauh, baik untuk kueri “tampilkan pool_nodes” dan untuk mencatat langkah-langkah serta menjalankan perintah.
- Saya menyalurkan beberapa info dbg ke /tmp/d melalui ssh, karena perintah akan dijalankan di sisi master, yang akan berubah setelah gagal
- Saya dapat menggunakan hasil "show pool_nodes" untuk mendapatkan info koneksi master yang sedang berjalan hanya dengan memfilter dengan klausa WHERE
- Saya memerlukan tanda kutip ganda dalam argumen untuk pg_rewind, yang perlu dijalankan di atas ssh, jadi saya hanya membagi perintah untuk keterbacaan, lalu echo dan jalankan
- Mempersiapkan recovery.conf berdasarkan output dari “show pool_nodes” (menulisnya saya bertanya pada diri sendiri - mengapa saya tidak menggunakan IP dan port pgpool saja?..
- Memulai failover slave baru (saya tahu saya seharusnya menggunakan langkah ke-2 - lewati saja untuk menghindari semua IP dan port ulang lagi)
Sekarang apa yang tersisa - mencoba menggunakan kekacauan ini di pcp:
[email protected]:~# pcp_recovery_node -h 127.0.0.1 -U vao -n 0 -w
pcp_recovery_node -- Command Successful
[email protected]:~# psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int)"
nid | port | st | role
-----+------+----+---------
0 | 5400 | up | standby
1 | 5401 | up | primary
2 | 5402 | up | standby
(3 rows)
Memeriksa /tmp/d di server pgpool:
[email protected]:~# cat /tmp/d
Tue May 1 11:37:59 IST 2018 ssh -T [email protected] /usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m2 promote
waiting for server to promote.... done
server promoted
online recovery started on u2 2018-05-01 /pg/10/m2/or_1st.sh /pg/10/m2
ssh -T 10.1.10.124 'pg_rewind -D --source-server="port=5401 host=10.1.10.147"'
ssh -T 10.1.10.124 pg_ctl -D start
OR finished 2018-05-01
Sekarang jelas kami ingin memutarnya lagi untuk melihat apakah itu berfungsi di host mana pun:
[email protected]:~$ ssh -T 10.1.10.147 pg_ctl -D /pg/10/m2 stop waiting for server to shut down.... done
server stopped
[email protected]:~$ psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int)"
nid | port | st | role
-----+------+------+---------
0 | 5400 | up | primary
1 | 5401 | down | standby
2 | 5402 | up | standby
(3 rows)
[email protected]:~# pcp_recovery_node -h 127.0.0.1 -U vao -n 1 -w
[email protected]:~$ psql -h localhost -p 5433 t -c"select nid,port,st,role from dblink('host=10.1.10.124 port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int)"
nid | port | st | role
-----+------+----+---------
0 | 5400 | up | primary
1 | 5401 | up | standby
2 | 5402 | up | standby
(3 rows)
Log terlihat serupa - hanya IP dan port yang berubah:
Tue May 1 11:44:01 IST 2018 ssh -T [email protected] /usr/lib/postgresql/10/bin/pg_ctl -D /pg/10/m promote
waiting for server to promote.... done
server promoted
online recovery started on u 2018-05-01 /pg/10/m/or_1st.sh /pg/10/m 10.1.10.147 /pg/10/m2 5400
ssh -T 10.1.10.147 'pg_rewind -D /pg/10/m2 --source-server="port=5400 host=10.1.10.124"'
ssh -T 10.1.10.147 pg_ctl -D /pg/10/m2 start
online recovery started on u 2018-05-01 /pg/10/m/or_1st.sh /pg/10/m
ssh -T 10.1.10.147 'pg_rewind -D --source-server="port=5400 host=10.1.10.124"'
ssh -T 10.1.10.147 pg_ctl -D start
OR finished 2018-05-01
Di kotak pasir ini, master pindah ke 5401 pada failover dan setelah tinggal di sana untuk sementara itu pindah kembali ke 5400. Menggunakan pg_rewind harus membuatnya secepat mungkin. Sebelumnya bagian yang menakutkan dari failover otomatis adalah - jika Anda benar-benar mengacaukan konfigurasi dan tidak melihat adanya force majeure, Anda dapat mengalami failover otomatis ke slave berikutnya dan berikutnya dan berikutnya hingga tidak ada lagi budak gratis yang tersisa. Dan setelah itu, Anda hanya akan mendapatkan beberapa master dengan otak terbelah dan tidak ada cadangan failover. Ini adalah penghiburan yang buruk dalam skenario seperti itu untuk memiliki lebih banyak budak untuk failover, tetapi tanpa pg_rewind Anda bahkan tidak akan memilikinya. rsync "Tradisional" atau pg_basebackup menyalin SEMUA $PGDATA untuk membuat standby, dan tidak dapat menggunakan kembali ex master yang "tidak terlalu berbeda".
Sebagai kesimpulan dari percobaan ini saya ingin menekankan sekali lagi - ini bukan solusi yang cocok untuk blind copy paste. Penggunaan pg_rewind tidak dianjurkan untuk pg_pool. Tidak dapat digunakan di semua ATM. Saya ingin menambahkan udara segar ke konfigurasi pgpool HA, untuk nubes seperti saya untuk mengamati sedikit lebih dekat cara kerjanya. Agar coryphaeus tersenyum pada pendekatan naivistik dan mungkin melihatnya dengan mata telanjang kita.