Di True Engineering, pada satu proyek, kebutuhan telah datang untuk mengubah versi PostgreSQL dari 9.6 menjadi 11.1.
Mengapa Basis data pada proyek ini sudah berukuran 1,5 Tb dan terus bertambah. Kinerja adalah salah satu persyaratan utama untuk sistem. Dan struktur data itu sendiri berkembang: kolom baru ditambahkan, yang sudah ada diubah. Versi baru Postgres telah belajar cara bekerja secara efisien dengan penambahan kolom baru dengan nilai default, sehingga tidak perlu memagari kruk kustom di tingkat aplikasi. Bahkan dalam versi baru, beberapa cara baru tabel partisi ditambahkan, yang juga sangat berguna dalam kondisi sejumlah besar data.
Jadi, sudah diputuskan, kami sedang bermigrasi. Tentu saja, Anda dapat meningkatkan versi baru dari server PostgreSQL bersamaan dengan yang lama, menghentikan aplikasi, menggunakan dump / restore (atau pg_upgrade) untuk memindahkan database, dan memulai aplikasi lagi. Solusi ini tidak cocok untuk kami karena ukuran pangkalan yang besar, di samping itu, aplikasi berfungsi dalam mode pertempuran, dan hanya ada beberapa menit untuk downtime.
Oleh karena itu, kami memutuskan untuk mencoba migrasi menggunakan replikasi logis di PostgreSQL menggunakan plugin pihak ketiga yang disebut
pglogical .
Dalam proses "percobaan", kami menemukan dokumentasi yang sangat terpisah tentang proses ini (dan dalam bahasa Rusia tidak sama sekali), serta beberapa jebakan dan nuansa yang tidak jelas. Pada artikel ini, kami ingin menyajikan pengalaman kami dalam bentuk Tutorial.
TL; DR- Semuanya ternyata (bukan tanpa kruk, artikel tentang mereka).
- Anda dapat bermigrasi dalam versi PostgreSQL dari 9,4 ke 11.x, dari versi mana saja ke bawah, ke atas atau ke atas.
- Waktu henti sama dengan waktu yang dibutuhkan aplikasi Anda untuk terhubung kembali ke server database baru (dalam kasus kami, itu adalah restart seluruh aplikasi, tetapi di alam liar, jelas, "opsi yang memungkinkan").
Mengapa solusi "dahi" tidak cocok untuk kita
Seperti yang telah kami katakan, jalan keluar yang paling mudah adalah menaikkan versi baru dari server PostgreSQL secara paralel dengan yang lama, menghentikan aplikasi, menggunakan dump / restore (atau pg_upgrade) untuk memindahkan database, dan memulai aplikasi lagi. Untuk database volume kecil, pada prinsipnya, ini adalah opsi yang cukup cocok (atau, dalam kasus umum, volume tidak penting ketika Anda memiliki opsi downtime aplikasi untuk periode "transfusi" database dari server lama ke yang baru, tidak peduli berapa lama waktu ini). Tetapi dalam kasus kami, basis data membutuhkan sekitar 1,5 Tb pada disk, dan memindahkannya bukan masalah beberapa menit, tetapi beberapa jam. Aplikasi ini, pada gilirannya, berfungsi dalam mode tempur, dan saya benar-benar ingin menghindari waktu henti selama lebih dari beberapa menit.
Juga terhadap opsi ini adalah kenyataan bahwa kami menggunakan replikasi Master-Slave dan tidak dapat dengan aman mematikan server Slave dari alur kerja. Jadi, untuk mengalihkan aplikasi dari versi PostgreSQL lama ke yang baru setelah migrasi dari server Master, perlu menyiapkan server Slave baru sebelum meluncurkan aplikasi. Dan ini adalah beberapa jam lagi downtime sampai Slave dibuat (walaupun jauh lebih sedikit daripada migrasi dari Master).
Oleh karena itu, kami memutuskan untuk mencoba migrasi menggunakan replikasi logis di PostgreSQL menggunakan plugin pihak ketiga yang disebut pglogical.
Informasi umum
pglogical adalah sistem replikasi logis menggunakan Decoding Logical asli dalam PostgreSQL dan diimplementasikan sebagai ekstensi PostgreSQL. Memungkinkan Anda mengonfigurasi replikasi selektif menggunakan model berlangganan / publikasi. Itu tidak memerlukan penciptaan pemicu dalam database atau penggunaan utilitas eksternal untuk replikasi.
Ekstensi berfungsi pada versi PostgreSQL apa pun, mulai dari 9,4 (sejak Decoding Logikal pertama kali muncul pada 9.4), dan memungkinkan Anda untuk bermigrasi di antara versi PostgreSQL yang didukung ke segala arah.
Menyiapkan replikasi secara manual menggunakan pglogical secara manual tidak terlalu sepele, meskipun pada prinsipnya sangat mungkin. Untungnya, ada
pgrepup utilitas pihak
ketiga untuk mengotomatisasi proses konfigurasi, yang akan kita gunakan.
Disk Space Memo
Karena kami berencana untuk meningkatkan versi baru PostgreSQL pada server yang sama secara paralel dengan yang lama, persyaratan disk untuk database pada server Master dan Slave menjadi dua kali lipat. Tampaknya ini sudah jelas, tapi ... Jaga cukup ruang kosong sebelum memulai replikasi, agar tidak menyesali tahun yang dihabiskan tanpa tujuan.
Dalam kasus kami, modifikasi database diperlukan, ditambah format penyimpanan selama migrasi antara 9,6 dan 11 "membengkak" tidak mendukung versi terbaru, sehingga ruang disk harus ditingkatkan bukan oleh 2, tetapi sekitar 2,2 kali. Puji LVM, ini bisa dilakukan dalam proses migrasi on the fly.
Secara umum, rawatlah itu.
Instal PostgreSQL 11 pada Master
Catatan: Kami menggunakan Oracle Linux, dan semua hal berikut akan dipertajam untuk distribusi ini. Ada kemungkinan bahwa distribusi Linux lainnya akan memerlukan sedikit revisi dengan sebuah file, tetapi sepertinya tidak akan signifikan.
Datadir lama terletak di
/var/lib/pgsql/9.6/data , yang baru, oleh karena itu, ada di
/ var / lib / pgsql / 11 / dataSalin pengaturan akses (
pg_hba.conf ) dan pengaturan server (
postgresql.conf ) dari 9,6 ke 11.
Untuk menjalankan dua server PostgreSQL pada mesin yang sama, dalam konfigurasi konfigurasi
postgresql.conf 11, ubah port menjadi 15432 (port = 15432).
Di sini Anda perlu berpikir hati-hati apa lagi yang perlu Anda lakukan dalam versi baru PostgreSQL khusus dalam kasus Anda, sehingga itu dimulai dengan
postgresql.conf Anda (dan aplikasi Anda akhirnya dapat bekerja dengannya). Dalam kasus kami, diperlukan untuk menginstal ekstensi PostgreSQL yang digunakan oleh kami di versi baru. Ini di luar ruang lingkup artikel, buat saja PostgreSQL baru mulai, bekerja, dan sepenuhnya cocok untuk Anda :)
Kami mencari di
/ var / lib / pgsql / 11 / data / pg_log / . Apakah semuanya baik-baik saja? Kami melanjutkan!
Instal dan konfigurasikan pgrepup

Nuansa:
- Sebagai app_owner kami menentukan pengguna yang menjalankan server PostgreSQL.
- Untuk Database, tentukan template1 .
- Nama Pengguna dan Kata Sandi - data untuk akses pengguna super. Dalam kasus kami, metode trust ditentukan dalam pg_hba.conf untuk koneksi lokal pengguna postgres , sehingga Anda dapat menentukan kata sandi secara sewenang-wenang.
Konfigurasikan Replikasi
Kami mendapatkan output dari daftar banyak parameter yang harus dikonfigurasi sesuai kebutuhan.
Contoh hasil verifikasi:


Semua kesalahan selama verifikasi harus dihilangkan. Dalam pengaturan kedua server harus ditetapkan
wal_level = LOGICAL (untuk Decoding Logical berfungsi), pengaturan yang diperlukan untuk mesin replikasi (jumlah slot dan
wal_sender ). Petunjuk utilitas pgrepup cukup informatif; pertanyaan tidak boleh muncul pada sebagian besar poin.
Kami membuat semua pengaturan yang diperlukan yang diminta pgrepup.
Dalam kedua file
pg_hba.conf kami menambahkan izin untuk pengguna yang akan melakukan replikasi, semua pada prompt pgrepup:
host replication pgrepup_replication 127.0.0.1/32 md5 host all pgrepup_replication 127.0.0.1/32 md5
Tambahkan Kunci Utama
Agar replikasi berfungsi, Kunci Utama harus didefinisikan di semua tabel.
Dalam kasus kami, PK tidak ada di mana-mana, oleh karena itu, pada saat replikasi, Anda perlu menambahkannya, dan pada akhir replikasi, jika perlu, hapus saja.
Daftar tabel tanpa PK, antara lain, menghasilkan
pgrepup check
. Untuk semua tabel dari daftar ini, Anda perlu menambahkan kunci utama dengan cara apa pun yang cocok untuk Anda. Dalam kasus kami, itu adalah sesuatu seperti:
ALTER TABLE %s ADD COLUMN temporary_pk BIGSERIAL NOT NULL PRIMARY KEY
Utilitas pgrepup memiliki perintah
pgrepup fix
untuk melakukan operasi ini (
pgrepup fix
), dan bahkan jika digunakan, diasumsikan bahwa jika replikasi berhasil, kolom sementara ini akan dihapus secara otomatis. Tapi, sayangnya, fungsi ini sangat ilusif dan mempesona buggy di pangkalan besar bahwa kami memutuskan untuk tidak menggunakannya, tetapi untuk melakukan operasi ini secara manual, karena nyaman bagi kami.
Instal ekstensi pglogical
Petunjuk untuk menginstal ekstensi dapat ditemukan di
sini . Ekstensi harus diinstal di kedua server.
Tambahkan beban pustaka di
postgresql.conf dari kedua server:
shared_preload_libraries = 'pglogical'
Pasang ekstensi pgl_ddl_deploy
Ini adalah ekstensi pembantu yang digunakan pgrepup untuk replikasi DDL logis.
Tambahkan beban pustaka di
postgresql.conf dari kedua server:
shared_preload_libraries = 'pglogical,pgl_ddl_deploy'
Memeriksa Perubahan
Sekarang menggunakan
pgrepup check
Anda perlu memastikan bahwa semuanya telah menjadi baik-baik saja dengan server target dan semua komentar mengenai server target telah sepenuhnya dihilangkan.
Jika semuanya baik-baik saja, Anda dapat me-restart server lama. Di sini Anda perlu memikirkan bagaimana aplikasi Anda akan bereaksi terhadap restart server database, mungkin Anda harus menghentikannya terlebih dahulu.
Sekarang dalam output dari perintah, semua item harus ditandai sebagai OK.
Tampaknya Anda dapat memulai migrasi, tetapi ...
Perbaiki bug pgrepup
Ada beberapa bug dalam versi pgrepup saat ini yang membuat migrasi menjadi tidak mungkin. Permintaan penarikan telah dikirim, tetapi sayangnya, permintaan itu diabaikan, jadi Anda harus melakukan koreksi secara manual.
Kami pergi ke folder instalasi pgrepup (case kami adalah
/usr/lib/python2.7/site-packages/pgrepup/commands/ ).
Lakukan sekali. Di setiap file
* .py , tambahkan
**kwargs
hilang dalam deskripsi fungsi. Gambar lebih baik daripada seribu kata:

Berkomitmen di
sini .
Lakukan dua. Di
setup.py kita melakukan pencarian untuk "sh -c", dua entri, semua perintah shell multi-line harus dibuat satu-baris.
Berkomitmen di
sini .
Mulai migrasi
Dengan perintah ini, pgrepup menyiapkan kedua server untuk memulai replikasi, membuat pengguna, mengkonfigurasi pglogical, mentransfer skema database.

Dia berkata, "Ayo pergi!" dan melambaikan tangannya:

Replikasi sedang berjalan. Situasi saat ini dapat dilihat menggunakan perintah
pgrepup status
:

Di sini kita melihat bahwa dua database telah dipindahkan dan replikasi sedang berlangsung, dan satu masih dalam proses pemindahan. Sekarang tinggal minum kopi dan menunggu sampai seluruh volume database asli dipompa.
Sepanjang jalan, Anda dapat melihat lebih dalam ke fasad pgrepup dan melihat apa yang terjadi di bawah tenda. Untuk pikiran yang ingin tahu, berikut adalah daftar pertanyaan sebagai titik awal:
SELECT * FROM pg_replication_origin_status ORDER BY remote_lsn DESC; SELECT *,pg_xlog_location_diff(s.sent_location,s.replay_location) byte_lag FROM pg_stat_replication s; SELECT query FROM pg_stat_activity WHERE application_name='subscription_copy'
Memiliki banyak kopi (di server pengujian saat menulis artikel ini, migrasi ~ 700Gb data berlangsung sekitar satu hari), kami akhirnya melihat gambar berikut:

Dan itu berarti saatnya untuk mempersiapkan seorang budak baru.
Instal PostgreSQL 11 di Slave
Di sini semuanya sederhana dan menurut buku teks, tidak ada nuansa.
Salin pengaturan akses (
pg_hba.conf ) dan pengaturan server (
postgresql.conf ) dari 9,6 ke 11. Dalam konfigurasi versi
postgresql.conf 11, ubah port ke 15432 (port = 15432)
# Master SELECT *,pg_wal_lsn_diff(s.sent_lsn,s.replay_lsn) AS byte_lag FROM pg_stat_replication s; # Slave SELECT now()-pg_last_xact_replay_timestamp();
Subtotal
Setelah semua prosedur ini, kami mendapatkan skema replikasi yang rumit ini:

Di sini, sebagai cek terakhir (dan, pada akhirnya, itu hanya indah), Anda dapat melakukan beberapa PEMBARUAN di database Master 9.6 dan melihat bagaimana itu direplikasi ke tiga server lainnya.

Mengalihkan aplikasi ke versi baru PostgreSQL
Sejauh ini, aplikasi kami belum mencurigai adanya versi baru PostgreSQL, saatnya untuk memperbaikinya. Opsi di sini pada dasarnya bergantung hanya pada dua hal:
Apakah Anda akan melebihi layanan baru pada port yang sama di mana yang lama bekerja,
dan apakah aplikasi Anda memerlukan restart ketika memulai kembali server database.
Untuk bersenang-senang, kami akan menjawab kedua pertanyaan "ya" dan melanjutkan.
Kami menghentikan aplikasi.
# , , : SELECT * FROM pg_stat_activity;


Kami mengembalikan port standar di konfigurasi
postgresql.conf versi baru ke Master dan Slave.
Pada Slave baru, kami juga mengubah port ke yang standar di
recovery.conf .
Sepanjang jalan, ada saran dari dosa untuk lebih lanjut mengubah port pada versi lama menjadi tidak aktif:
Kami mengekspos port non-standar di
postgresql.conf dari versi lama ke Master dan Slave.
Pada Slave lama, kami juga mengubah port ke yang non-standar di
recovery.conf .
Periksa log.
Periksa status replikasi pada Master.
SELECT *,pg_wal_lsn_diff(s.sent_lsn,s.replay_lsn) AS byte_lag FROM pg_stat_replication s;
Kami meluncurkan aplikasi. Kami senang selama setengah jam.
Dan akhirnya, literatur yang bermanfaat tentang topik:Semoga beruntung