PostgreSQL hadir dengan serangkaian fitur luar biasa, tak tertandingi di ruang RDBMS open-source. Sebagian besar mudah dipelajari dan digunakan, terutama untuk pengembang aplikasi. Namun, beberapa bagian memang tidak mudah. Mereka membutuhkan pekerjaan untuk penyiapan dan mendapatkan yang benar, dan biasanya juga sangat penting untuk misi.
Manajemen Koneksi
PostgreSQL meluncurkan proses baru, yang disebut proses backend , untuk menangani setiap koneksi. Ini berbeda dengan arsitektur penanganan koneksi berbasis eventloop/threadpool modern yang ditemukan di perangkat lunak server lain yang sebanding. Memunculkan proses penuh membutuhkan lebih banyak waktu dan sumber daya, dan bermanifestasi sebagai peningkatan latensi kueri dalam aplikasi di mana koneksi dibuka dan ditutup dengan kecepatan tinggi.
Di sebagian besar penerapan, penyatuan koneksi diperlukan pada tingkat tertentu. Pada tingkat aplikasi, ini dapat menggunakan bahasa pemrograman/fitur perpustakaan Anda. Misalnya sql/DB.SetMaxIdleConnsdapat digunakan untuk meningkatkan penggunaan kembali koneksi dari dalam satu aplikasi Go.
Namun seringkali, Anda harus menggunakan penyatuan koneksi pihak ketiga atau solusi penyeimbangan beban. Pengumpul koneksi memelihara kumpulan koneksi idle ke server Postgres hulu, yang ditetapkan dan diproksikan ke koneksi klien yang masuk. Mereka biasanya mengurai SQL yang dikirim oleh klien untuk mengenali batas transaksi dan DML yang memodifikasi data untuk mengimplementasikan fitur seperti penyatuan koneksi tingkat transaksi dan replika baca.
PgBouncer adalah pooler koneksi biner tunggal yang populer, ringan, dan sering dijalankan bersama PostgreSQL dalam sistem yang sama.
PgPool lebih serbaguna daripada PgBouncer. Itu juga dapat melakukan load balancing dan replikasi misalnya.
Penyatuan koneksi membawa masalah tersendiri. Pertama, ini adalah bagian bergerak tambahan yang telah dipertahankan dalam penerapan Anda. Menyiapkan autentikasi juga sulit jika Anda memiliki klien yang menggunakan kredensial atau mekanisme autentikasi yang berbeda. Beberapa fitur tingkat koneksi seperti LISTEN/NOTIFY, pernyataan yang disiapkan, tabel sementara, dan sejenisnya mungkin memerlukan konfigurasi tambahan atau perubahan sisi klien agar berfungsi.
Nol Peningkatan Waktu Henti
Memutakhirkan PostgreSQL antara versi minor (13.x -> 13.y) melibatkan pemasangan paket baru dan memulai ulang proses server. Meskipun memulai ulang proses server pasti akan mengganggu semua klien yang terhubung, ini masih merupakan pertanyaan yang masuk akal, mengingat waktu henti terkait dengan durasi layanan dimulai ulang.
Memutakhirkan antara versi utama (12.x -> 13.y), bagaimanapun, adalah masalah yang jauh lebih besar. Biasanya, semakin banyak data yang ada, semakin sulit prosesnya.
Metode paling sederhana, yang hanya berfungsi untuk jumlah data yang rendah (misalnya puluhan GB), adalah membuang data dari versi lama dan mengembalikannya ke server versi baru. Opsi lainnya adalah menggunakan pg_upgrade, yang memerlukan tarian yang diatur melibatkan biner dari kedua versi Postgres.
Dalam kedua kasus, database akan down untuk waktu yang cukup lama.
Idealnya, mungkin untuk mereplikasi ke server versi baru, dan mempromosikan server versi baru sebagai yang utama. Namun, replikasi streaming tidak mungkin dilakukan ke server siaga dengan versi utama yang berbeda. Replikasi logis, meskipun terlihat cocok untuk pekerjaan itu, memiliki beberapa hal yang perlu dikerjakan untuk memastikan replikasi lengkap.
Sebagian besar solusi HA untuk Postgres mengandalkan replikasi streaming, dan oleh karena itu Anda tidak dapat mengupgrade node dalam cluster satu per satu.
Keadaan seni saat ini adalah menggunakan replikasi logis, sambil mengatasi keterbatasan replikasi logis, dan mungkin melibatkan pembatasan fitur yang dapat digunakan aplikasi (seperti DDL) selama fase peningkatan.
Ketersediaan Tinggi
PostgreSQL hadir dengan semua fitur tingkat rendah yang diperlukan untuk membangun solusi HA:replikasi dengan umpan balik, replikasi berjenjang, replikasi sinkron, siaga, siaga panas, promosi siaga, dan sebagainya. Namun, itu tidak benar-benar memberikan solusi HA di luar kotak. Tidak ada kerangka kerja atau alat untuk memantau kesehatan dan secara otomatis melakukan failover ke standby. Tidak ada gagasan tentang cluster HA multi-node.
Anda harus menyiapkan dan menjalankan solusi pihak ketiga untuk membuat penerapan Postgres dengan ketersediaan tinggi. Favorit saat ini adalahpg_auto_failover dan Patroni. Sementara Patroni bergantung pada penyimpanan konfigurasi yang sangat tersedia seperti ZooKeeper atau dll, pg_auto_failover dapat melakukannya tanpanya.
Mengevaluasi, menerapkan, dan menguji salah satunya dalam produksi membutuhkan waktu dan usaha. Playbook pemantauan, peringatan, dan operasi harus disiapkan dan dipelihara.
Manajemen Kembung
Arsitektur MVCC PostgreSQL berarti bahwa tidak ada data yang pernah ditimpa – memodifikasi baris hanya menghasilkan versi baru dari baris yang ditulis ke disk. Menghapus baris hanya berarti merekam bahwa baris tersebut tidak terlihat oleh transaksi di masa mendatang. Ketika versi baris tidak dapat diakses dari transaksi yang sedang berlangsung atau yang akan datang, itu tidak lagi berguna, dan disebut "mengembang". Proses pengumpulan sampah kembung ini disebut “vakum”.
Bloat tidak terlihat oleh aplikasi, dan hanya menjadi sakit kepala DBA. Untuk tabel yang banyak memperbarui, memantau dan mengelola bloat adalah masalah yang tidak sepele. Proses autovacuum banyak membantu, tetapi ambang batasnya mungkin perlu disetel pada tingkat global atau per- tablelevel untuk memastikan ukuran tabel tidak terlalu besar.
Indeks juga dipengaruhi oleh kembung, dan autovacuum tidak membantu di sini. Penghapusan baris dan pembaruan kolom yang diindeks menyebabkan entri mati dalam indeks. Perbarui-beban kerja yang berat dengan pembaruan ke kolom yang diindeks dapat menyebabkan indeks terus bertambah dan tidak efisien. Tidak ada yang setara dengan vakum untuk indeks. Satu-satunya solusi adalah membangun kembali seluruh indeks menggunakan REINDEX atau menggunakan VACUUM FULL pada tabel.
Selain satu nilai per tabel (pg_stat_all_tables.n_dead_tup), Postgres tidak menawarkan apa pun untuk memperkirakan kembung dalam tabel, dan tidak sama sekali untuk indeks. Cara paling praktis masih tetap menjalankan kueri yang tampak menakutkan dari check_postgres.
pgmetrics menggabungkan kueri dari check_postgres, dan dapat menghasilkan output format JSON dan CSV yang menyertakan informasi ukuran dan mengasapi untuk semua tabel dan indeks; yang dapat dimasukkan ke dalam alat pemantauan atau otomatisasi.
pg_repack adalah alternatif populer untukVACUUM FULL – ia dapat melakukan pekerjaan yang sama tetapi tanpa kunci. Jika Anda terpaksa melakukan VACUUM FULL secara teratur, ini adalah alat yang harus diselidiki.
zheap adalah mesin penyimpanan baru untuk Postgres yang telah dikembangkan selama bertahun-tahun, yang menjanjikan untuk mengurangi pembengkakan melalui pembaruan di tempat.
Pengelolaan Paket Kueri
Core PostgreSQL hanya menawarkan dua alat dasar di ruang ini:
- pg_stat_statements ekstensi untuk analitik kueri – ini memberikan total dan rata-rata perencanaan kueri dan waktu eksekusi, penggunaan disk dan memori
- penjelasan_otomatis ekstensi, yang dapat mencetak rencana eksekusi kueri ke tujuan log Postgres
Sementara statistik yang disediakan oleh pg_stat_statements cukup untuk bertahan, menggunakan auto_explain untuk memaksa rencana ke dalam file log dan kemudian mengekstraknya tidak lebih dari peretasan terutama dibandingkan dengan pesaing komersial Postgres, yang menawarkan riwayat rencana, fitur dasar dan manajemen.
Keadaan seni saat ini dengan Postgres adalah untuk menambang rencana permintaan file log dan menyimpannya di tempat lain. Tetapi mungkin masalah yang paling mengganggu adalah tidak dapat mengaitkan rencana kueri dengan analisis yang sesuai dari pg_stat_statements. Cara pgDash melakukannya adalah dengan mem-parsing teks kueri SQL dari pg_stat_statements dan output auto_explain, menyesuaikan mangling yang dilakukan oleh pg_stat_statements, dan mencoba mencocokkan keduanya. Ini membutuhkan parser SQL dialek PostgreSQL lengkap.
Membuat dasar, menetapkan kebijakan untuk pemilihan rencana, dll. tidak mungkin dilakukan di inti PostgreSQL saat ini.
Ada beberapa ekstensi di luar sana yang pada dasarnya merupakan versi perbaikan dari pg_stat_statements, tetapi langkah-langkah tambahan yang terlibat dalam menggunakan ekstensi pihak ketiga membuatnya menjadi tantangan bagi kebanyakan orang, terutama jika mereka menggunakan penyedia Postgres terkelola.
Menyetel
PostgreSQL memiliki banyak opsi penyetelan, mulai dari pengaturan under-configured-by-defaultshared_buffers. Beberapa mudah dipahami dan diatur, seperti jumlah pekerja paralel untuk berbagai operasi (proses_pekerja_maks, proses_pekerja_maks, dll). Area lain agak tidak jelas (wal_compression, random_page_cost dll) tetapi umumnya bermanfaat. Namun, yang paling menjengkelkan adalah yang membutuhkan informasi terukur tentang beban kerja.
Misalnya, jika work_mem terlalu rendah, kueri mungkin menggunakan file disk sementara; jika terlalu tinggi, dan ada cukup kueri simultan, proses backend Postgres mungkin dimatikan OOM. Jadi, bagaimana Anda mengetahui nomor yang akan disetel?
Secara praktis, terutama dengan beban kerja OLTP dan beban kerja aplikasi web, tidak mungkin untuk memprediksi berapa permintaan memori puncak untuk kueri. Taruhan terbaik Anda adalah menetapkan nilai yang wajar, lalu memantau kueri untuk melihat apakah ada di antara mereka yang dapat memperoleh manfaat dari nilai work_mem yang lebih tinggi.
Dan bagaimana Anda melakukannya? Anda harus mendapatkan ekstensi auto_explain untuk mencatat rencana eksekusi kueri setiap kueri, mengekstraknya dari file log Postgres, memeriksa setiap rencana kueri untuk melihat apakah paket tersebut menggunakan penggabungan eksternal berbasis disk atau pemindaian heap bitmap dengan blok heap lossy.
Bukan tidak mungkin, hanya sulit.