Dalam beberapa bulan terakhir saya telah mengerjakan peningkatan online untuk database yang sangat besar sebagai bagian dari proyek AXLE dan saya ingin berbagi pemikiran saya tentang topik tersebut dan kemajuan apa yang telah kami buat baru-baru ini.
Sebelum bergabung dengan 2ndQuadrant, saya dulu bekerja di Skype di mana bisnis tidak mengizinkan jendela pemeliharaan untuk database kami. Ini berarti tidak ada waktu henti yang diizinkan untuk penerapan, peningkatan, dll. Aturan semacam itu membuat Anda mengubah cara Anda melakukan sesuatu. Sebagian besar perubahan kecil, Anda tidak melakukan kunci berat, Anda memiliki replika untuk memungkinkan kegagalan cepat. Namun meskipun Anda dapat membuat rilis Anda kecil dan tidak memblokir, apa yang terjadi bila Anda perlu melakukan pemutakhiran versi utama dari database PostgreSQL?
Anda mungkin berada dalam situasi yang berbeda, karena sebagian besar perusahaan memiliki jendela pemutakhiran, sehingga Anda mungkin mengalami waktu henti selama pemutakhiran. Namun ini membawa dua masalah. Pertama, tidak ada perusahaan yang benar-benar menyukai waktu henti meskipun diizinkan. Dan yang lebih penting setelah database Anda tumbuh melebihi ukuran gigabyte menjadi kisaran terabyte atau ratusan terabyte, waktu henti dapat memakan waktu berhari-hari atau bahkan berminggu-minggu dan tidak ada yang mampu menghentikan operasi mereka selama itu. Hasilnya adalah banyak perusahaan sering melewatkan peningkatan penting, membuat yang berikutnya bahkan lebih menyakitkan. Dan para pengembang kehilangan fitur baru, peningkatan kinerja. Mereka (perusahaan) terkadang bahkan berisiko menjalankan versi PostgreSQL yang tidak lagi didukung dan telah mengetahui kerusakan data atau masalah keamanan. Dalam paragraf berikut, saya akan berbicara sedikit tentang pekerjaan saya untuk membuat pemutakhiran lebih sedikit memakan waktu dan sebagai hasilnya tidak terlalu menyakitkan dan mudah-mudahan lebih sering.
Mari saya mulai dengan sedikit sejarah dulu. Sebelum PostgreSQL 9.0, satu-satunya cara untuk melakukan peningkatan versi utama adalah dengan menjalankan pg_dump dan memulihkan dump ke dalam instance yang menjalankan versi PostgreSQL yang lebih baru. Metode ini membutuhkan struktur dan semua data untuk dibaca dari database dan ditulis ke dalam file. Kemudian baca dari file dan dimasukkan ke database baru, indeks harus dibangun kembali, dll.
Seperti yang Anda bayangkan, proses ini bisa memakan waktu cukup lama. Peningkatan kinerja dibuat di 8.4 untuk pg_restore dengan opsi -j ditambahkan di mana Anda dapat menentukan berapa banyak pekerjaan paralel yang akan dijalankan. Ini memungkinkan untuk memulihkan beberapa tabel (indeks, dll) secara paralel sehingga membuat proses pemulihan lebih cepat untuk dump format kustom. Versi 9.3 menambahkan opsi serupa ke pg_dump, meningkatkan kinerja lebih jauh. Namun mengingat seberapa cepat volume data tumbuh, paralelisasi itu sendiri tidak cukup untuk membuat keuntungan serius dalam waktu yang dibutuhkan untuk upgrade.
Kemudian di PostgreSQL 9.0 sebuah utilitas bernama pg_upgrade tiba. Pg_upgrade hanya membuang struktur dan mengembalikannya ke cluster baru. Tapi itu menyalin file data seperti yang ada di disk yang jauh lebih cepat daripada membuangnya ke format logis dan kemudian memasukkannya kembali. Ini cukup baik untuk database kecil karena ini berarti waktu henti dalam kisaran menit atau jam, waktu yang dapat diterima untuk banyak skenario. Ada juga mode tautan yang hanya membuat tautan keras (titik persimpangan di Windows) yang membuat proses ini lebih cepat. Tetapi dari sudut pandang pribadi saya, terlalu berbahaya untuk menjalankan pengaturan seperti itu di server master produksi. Saya akan menjelaskan secara singkat mengapa. Jika terjadi kesalahan, setelah Anda memulai server baru yang ditingkatkan menggunakan mode tautan, Anda tiba-tiba tanpa basis data produksi dan harus gagal, atau lebih buruk lagi, Anda harus memulihkan dari cadangan. Itu berarti Anda tidak hanya gagal meningkatkan versi tetapi juga menyebabkan waktu henti tambahan! Semoga berhasil mendapatkan persetujuan lain kali.
Sekarang banyak orang yang tidak mampu membayar waktu henti yang lama untuk pemutakhiran menggunakan solusi replikasi berbasis pemicu seperti Slony atau Londiste untuk melakukan pemutakhiran. Ini adalah solusi yang baik karena Anda dapat mereplikasi data Anda saat server asli sedang berjalan dan kemudian beralih dengan waktu henti yang minimal. Namun dalam praktiknya ada beberapa masalah. Salah satunya adalah bahwa solusi berbasis pemicu sering kali sulit diatur, terutama jika Anda melakukannya hanya sekali setiap beberapa tahun dan hanya untuk melakukan peningkatan. Juga mudah untuk melewatkan tabel atau menambahkan tabel dalam urutan yang salah dan dengan demikian tidak mendapatkan salinan lengkapnya. Saya telah menyaksikan ini dalam praktik dan orang-orang yang melakukan peningkatan bekerja dengan replikasi berbasis pemicu setiap hari . Masalah lainnya adalah bahwa solusi berbasis pemicu menambah beban yang cukup besar pada basis data sumber, terkadang membuat pemutakhiran menjadi tidak mungkin karena server basis data menjadi kelebihan beban setelah replikasi diaktifkan. Dan yang tak kalah pentingnya, dibutuhkan waktu yang sangat lama untuk replikasi berbasis pemicu untuk benar-benar memindahkan data ke server baru. Pada kesempatan terakhir saya terlibat dengan proyek peningkatan, solusi berbasis pemicu membutuhkan waktu sekitar satu bulan untuk menyalin database dan mengejar perubahan. Ya, satu bulan.
Dengan PostgreSQL 9.4 hadir fitur decoding logis yang menawarkan awal baru untuk merancang solusi masalah peningkatan online yang baru dan lebih baik. Apa yang kami lakukan, sebagai bagian dari proyek AXLE, adalah membuat alat yang menggabungkan decoding logis dengan teknik yang dijelaskan di atas. Solusinya memecahkan sebagian besar masalah dari pendekatan sebelumnya. Ekstensi PostgreSQL Replikasi Uni-Directional (disingkat UDR) melakukan replikasi logis menggunakan decoding logis dari log tulis depan (WAL). Berkat ini, dampak pada server master hampir setara dengan replikasi streaming fisik, sehingga beban tambahan yang disebabkan oleh peningkatan berkelanjutan minimal pada sistem yang berjalan. Juga menyediakan alat untuk menginisialisasi node baru, baik menggunakan cadangan fisik dan logis. Anda bahkan dapat mengubah siaga fisik yang ada menjadi siaga UDR. Dan karena ini adalah sistem replikasi logis, dimungkinkan untuk mendesainnya dengan cara yang mendukung replikasi lintas versi.
Artinya, sekarang kita dapat menggunakan UDR dalam kombinasi dengan pg_upgrade untuk melakukan upgrade online dari versi PostgreSQL utama dengan waktu henti yang minimal, dalam waktu yang singkat dan dengan dampak minimal pada sistem yang sedang berjalan.
Contoh tampilannya dalam praktik:
- Lakukan pg_basebackup dari instance yang ada.
- Siapkan replikasi UDR antara instance asli dan yang dibuat oleh basebackup.
- Pg_upgrade instance baru.
- Biarkan UDR memutar ulang perubahan yang terjadi sementara itu.
- Ganti lalu lintas ke instance baru.
Untuk cara dengan instruksi yang lebih rinci, lihat panduan Peningkatan Online UDR di wiki PostgreSQL. Sumber UDR tersedia di repositori 2ndquadrant_bdr di server git PostgreSQL (bdr-plugin/cabang berikutnya).
Terakhir, karena UDR bukan hanya alat pemutakhiran online tetapi juga solusi replikasi, UDR dapat digunakan untuk kebutuhan replikasi normal Anda, alih-alih replikasi streaming fisik. Selain itu, ia memberikan beberapa keuntungan seperti kemampuan untuk membuat tabel sementara, mereplikasi dari beberapa database OLTP ke dalam satu database gudang data besar, atau mereplikasi hanya sebagian dari database.
Harapan saya adalah bahwa upaya ini akan berarti bahwa pertimbangan waktu henti tidak lagi menjadi masalah dalam hal memutakhirkan dari PostgreSQL 9.4 ke atas ke versi utama yang baru.
Penelitian yang mengarah pada hasil ini telah menerima dana dari Program Kerangka Ketujuh Uni Eropa (FP7/2007-2013) di bawah perjanjian hibah n° 318633.