PostgreSQL: Tidak Ada Lagi VACUUM maupun Bloat
(orioledata.com)- Engine penyimpanan baru untuk PostgreSQL, OrioleDB, menghapus proses VACUUM yang boros sumber daya dan menyelesaikan masalah bloat pada tabel
- PostgreSQL lama membutuhkan vacuum manual dan autovacuum karena struktur MVCC, dan kedua pendekatan tersebut mengonsumsi sumber daya sistem yang cukup besar
- OrioleDB menangani perubahan data secara efisien dan menggabungkan data yang terfragmentasi melalui undo log tingkat baris dan blok serta penggabungan halaman otomatis
- Dalam benchmark sintetis, OrioleDB mencapai TPS 5 kali lebih tinggi dan penghematan sumber daya dengan hanya memperbarui satu indeks, menggabungkan halaman jarang secara otomatis, dan menerapkan WAL tingkat baris
- Dengan menyelesaikan tantangan lama bernama VACUUM, OrioleDB mengurangi beban pemeliharaan serta menghadirkan peningkatan performa dan pengalaman pengguna PostgreSQL
Sejarah dan Keterbatasan VACUUM PostgreSQL
- Proses VACUUM adalah warisan historis yang berasal dari konsep infinite time-travel dalam proyek Berkley Postgres; konsep tersebut kemudian ditinggalkan oleh komunitas
- Namun, hal ini mengarah pada implementasi sistem MVCC (Multi-Version Concurrency Control) yang rentan terhadap bloat tabel
- MVCC menguntungkan untuk pemrosesan transaksi konkuren, tetapi memperkenalkan kebutuhan vacuuming manual untuk membersihkan data lama dan tidak diperlukan
- Vacuuming manual adalah pekerjaan padat tenaga dan berpotensi menjadi penyebab inefisiensi sistem
- Setelah itu, autovacuum yang terotomatisasi diperkenalkan untuk mengurangi beban pekerjaan manual
- Ini merupakan kemajuan besar, tetapi bukan solusi sempurna; meskipun otomatis, tetap mengonsumsi sumber daya sistem yang signifikan
- Hal ini disebut sebagai salah satu alasan Uber bermigrasi dari PostgreSQL ke MySQL, sekaligus salah satu dari 10 keluhan Richard Branson tentang PostgreSQL
- Dengan diperkenalkannya pembaruan Heap-Only Tuples (HOT) dan microvacuum, kebutuhan untuk melakukan vacuum seluruh tabel berkurang
- Meski begitu, VACUUM tetap menjadi operasi yang intensif sumber daya, dan tabel masih rentan terhadap bloat
- Ini disebut sebagai bagian PostgreSQL yang paling tidak disukai oleh tim OtterTune
- Terlepas dari keterbatasan tersebut, banyak organisasi dan pengembang terus menggunakan PostgreSQL karena ketangguhan, skalabilitas, dan komunitasnya yang kuat
- OtterTune mengakui masalahnya, tetapi memutuskan untuk tetap menggunakan PostgreSQL
Fitur Inti OrioleDB
- OrioleDB adalah engine PostgreSQL baru yang dikembangkan dengan tujuan utama melindungi tabel dari bloat dan menghapus kebutuhan pemeliharaan berkala seperti VACUUM
- Hal ini diwujudkan melalui undo log tingkat baris dan tingkat blok serta penggabungan halaman otomatis
- Undo log tingkat baris dan blok memberikan kontrol yang lebih halus untuk menangani perubahan data secara efisien
- Fitur penggabungan halaman otomatis terus menggabungkan data yang terfragmentasi di background
- Cara kerja masing-masing teknik
- Undo log tingkat baris memungkinkan pembaruan in-place
- Undo log tingkat blok menghapus tuple yang sudah dihapus tetapi masih terlihat oleh sebagian transaksi dari penyimpanan utama, sehingga menyediakan ruang untuk tuple baru
- Penggabungan otomatis pada halaman jarang melindungi tabel dan indeks dari bloat bahkan setelah banyak penghapusan
- Hasilnya, intervensi manual berkurang, konsumsi sumber daya menurun, dan kerentanan terhadap bloat tabel menjadi lebih rendah
Benchmark
- Benchmark sintetis disusun dengan skrip inisialisasi yang membuat 1 tabel dan 5 indeks
- Membuat tabel
testdengan primary keyidserta kolomvalue1~value4(float8) dants(timestamp) - Membuat indeks masing-masing pada
value1,value2,value3,value4, dants
- Membuat tabel
- Skrip pgbench berbentuk upsert yang memperbarui satu indeks secara jarang saat terjadi konflik
- Melakukan INSERT dengan
idacak dalam rentang 1–10.000.000; saat terjadi konflik, hanyatsyang diperbarui - Pembaruan jarang ini menyebabkan bloat indeks pada tabel heap PostgreSQL biasa
- Melakukan INSERT dengan
- Keunggulan desain OrioleDB yang ditunjukkan benchmark ini
- Berkat undo log dan pembaruan in-place, OrioleDB hanya memperbarui satu indeks yang nilainya berubah, sedangkan engine heap PostgreSQL memperbarui semua indeks karena pembaruan satu field indeks menonaktifkan HOT
- Penggabungan halaman otomatis melindungi indeks jarang dari bloat, dan halaman jarang digabungkan secara otomatis
- WAL tingkat baris membutuhkan ruang jauh lebih sedikit dibanding WAL tingkat blok, sehingga mengurangi IOPS saat pencatatan WAL
- Angka yang diberikan OrioleDB sebagai hasil peningkatan kumulatif
- TPS 5 kali lebih tinggi per transaksi
- Beban CPU 2,3 kali lebih rendah per transaksi
- IOPS 22 kali lebih rendah per transaksi
- Tidak ada bloat pada tabel maupun indeks
Signifikansi OrioleDB
- Dengan hadirnya OrioleDB, komunitas PostgreSQL memasuki era baru ketika VACUUM menjadi bagian dari masa lalu
- OrioleDB menawarkan solusi untuk salah satu tantangan tertua PostgreSQL, sekaligus memberikan peningkatan efisiensi dan pengurangan beban pemeliharaan bagi pengguna
1 komentar
Komentar Hacker News
Meski begitu, ada beberapa hal yang mengganjal. Pemrosesan per baris menimbulkan masalah penyelarasan penulisan dan penyelarasan fsync, sementara halaman lebih mudah disejajarkan daripada baris berukuran arbitrer
PostgreSQL sangat, mungkin bahkan ekstrem, konservatif soal keamanan data, dan ini terutama dicapai dengan fsync pada waktu yang tepat; dampaknya menyebar ke seluruh stack I/O, termasuk firmware SSD, sehingga menjadi lambat
MVCC sangat bagus untuk akses bersamaan, tetapi dokumen Oriole tidak menjelaskan grafik itu berasal dari kondisi konkurensi seperti apa
Judul dan pengantar dokumen Oriole berfokus pada menyelesaikan VACUUM, tetapi rasanya belum membuktikan bahwa grafik “gelombang kotak” yang terlihat di PostgreSQL memang sebagian besar disebabkan oleh VACUUM. Benchmark lain dari Percona (https://www.percona.com/blog/evaluating-checkpointing-in-postgresql/) tidak menunjukkan pola gelombang kotak yang sejelas itu
Para penulis tentu mengetahui masalah-masalah ini, jadi mungkin bisa menuliskan gambaran umum tentang bagaimana mereka menanganinya
https://github.com/orioledb/orioledb/blob/main/doc/arch.md
Karena PostgreSQL konservatif soal keamanan data, target pertama adalah menjadikannya ekstensi murni. Agar menjadi bagian dari PostgreSQL, perlu pembuktian oleh waktu
Benar bahwa informasi konkurensi belum ada, dan informasi tipe VM serta konkurensi sudah ditambahkan ke posting blog
Pola gelombang kotak memang disebabkan oleh checkpoint. Penyebab peningkatan di sini sebenarnya bukan VACUUM, melainkan cara yang hanya memperbarui indeks terkait, serta WAL per baris yang mengurangi total I/O
Keren sih, tetapi saya penasaran bagaimana rencananya mengikuti siklus rilis proyek induknya
Mereka mem-fork proyek open source besar lalu menambahkan perubahan yang cukup besar, dan jika perubahan itu tidak dianggap akan diterima upstream, saya tidak yakin ini ide yang bagus
Perlu diperjelas apakah ini mainan yang dibuat untuk bersenang-senang, atau proyek serius yang akan dipelihara ke depan
Jika ini proyek serius, harus dijelaskan rencananya agar tidak menjadi software yang ditinggalkan di masa depan, rencana untuk menyerap rilis mendatang dari proyek asal, atau rencana untuk bercabang menjadi proyek yang sepenuhnya terpisah
Karena ini ekstensi, sepertinya masih bisa menerima perubahan upstream PostgreSQL, tetapi kalau itu mudah, mestinya sejak awal sudah menjadi bagian dari proyek PostgreSQL, jadi tampaknya tidak semudah itu
“Benar. Tapi jalannya masih panjang. Saat ini OrioleDB adalah ekstensi yang disertakan bersama patch core PostgreSQL. Target jangka menengah adalah menjadikan OrioleDB ekstensi murni, dan target jangka panjang adalah menjadikan OrioleDB bagian dari core PostgreSQL”
Lain kali sebaiknya jangan langsung masuk sekeras ini sejak awal
https://news.ycombinator.com/item?id=36742001
Melihat contoh perbaikannya sendiri jelas membantu. Jika perusahaan punya sumber daya untuk memelihara fork Postgres, bagus; kalau tidak, tinggal menilai apakah kesulitan memakai fork ini sepadan dibanding peningkatan performanya
Saya berharap pembicaraan seperti “Uber pindah dari Postgres ke MySQL” tidak diulang lagi. Uber sebenarnya berpindah dari Postgres yang digunakan sebagai basis data relasional ke sesuatu yang pada praktiknya merupakan basis data non-relasional buatan sendiri, dengan MySQL dipakai sebagai penyimpanan key-value terdistribusi, jadi situasinya tidak bisa langsung diterapkan ke sebagian besar pengguna Postgres
Bagaimanapun, desain MVCC seperti ini, yang memindahkan data lama ke undo log/segmen, juga digunakan di Oracle DB, sehingga mekanismenya sendiri sudah teruji
Kesulitan umumnya adalah membaca versi data lama menjadi lebih lambat. Data harus dicari di log, dan kadang-kadang data sudah dihapus dari log sebelum transaksi selesai, sehingga bisa muncul galat terkenal Snapshot Too Old
Di artikel saya tidak melihat kapan baris dihapus dari undo log. Jika dihapus ketika tidak lagi dibutuhkan, tampaknya diperlukan pekerjaan pengelolaan dalam jumlah serupa, jadi saya kurang paham dari mana peningkatannya berasal. Jika berupa buffer sirkular yang ruangnya bisa habis seperti Oracle, transaksi yang berjalan lama akan mulai gagal pada beban tulis tinggi, dan itu cukup menjengkelkan
Tergantung apa tepatnya yang dimaksud dengan “pekerjaan pengelolaan”. Jika melihat jumlah pekerjaannya, undo record lama bisa dihapus secara batch dengan sangat murah, misalnya dengan melakukan unlink file, sehingga ada peningkatan. Tidak perlu pemindaian VACUUM
Jika melihat penggunaan ruang, benar bahwa jumlah versi yang sama akan memakai jumlah ruang yang sama. Namun, menaruh versi baris lama di penyimpanan terpisah dapat mencegah degradasi jangka panjang pada penyimpanan utama. OrioleDB juga mengimplementasikan penggabungan otomatis untuk halaman sparse
OrioleDB mengimplementasikan buffer sirkular dalam memori untuk undo log. Jika buffer sirkular tidak mampu menampung semua undo record, record tertua dipindahkan ke penyimpanan. Saat ini tidak ada batas ukuran undo log, dan record dipertahankan selama masih mungkin dibutuhkan oleh transaksi mana pun, sehingga tidak ada galat “Snapshot Too Old”
Namun, bisa dipertimbangkan untuk mengimplementasikan galat ala Oracle sebagai opsi agar ukuran undo dapat dibatasi. Ada baiknya juga melihat dokumen arsitektur di GitHub
https://github.com/orioledb/orioledb/blob/main/doc/arch.md
Tentu saja MySQL menghindari VACUUM dengan banyak berkompromi pada aspek konkurensi
Judulnya membuat saya berharap banyak, tetapi kesan pertama terasa membuat frustrasi. README utama di GitHub[1] terasa seperti kalimat promosi korporat
Sejauh ini yang saya pahami hanyalah OrioleDB adalah mesin penyimpanan baru untuk PostgreSQL, PostgreSQL adalah basis data yang “paling dicintai”, OrioleDB adalah ekstensi yang dibangun di atas ekstensi lain, dan OrioleDB membuka pintu ke cloud
Setelah lewatnya penipuan kripto dan Web 3.0, saya kira pendekatan seperti ini akan dihindari saat merilis proyek yang memperluas dan memperbaiki sesuatu sepenting PostgreSQL
[1] https://github.com/orioledb/orioledb
Rasanya sulit menuliskannya lebih jelas dari itu. Table access method adalah fitur yang diperkenalkan ke PostgreSQL untuk mendukung metode penyimpanan alternatif seperti zheap atau penyimpanan berorientasi kolom
Menyebut fakta ini penting. Ada cukup banyak fork PostgreSQL yang menambahkan sistem penyimpanan data alternatif, sedangkan OrioleDB dirancang agar berjalan sebagai ekstensi pada PostgreSQL yang tidak di-fork. Saat ini belum sepenuhnya demikian, tetapi arahnya ke sana
Jika terbiasa dengan PostgreSQL, README itu tampak cukup jelas
Desain Oriole tampaknya membutuhkan indeks yang sadar transaksi dan penghapusan entri per titik, dan ini punya biaya tersendiri
Misalnya, padanan GiST untuk indeks spasial tampaknya akan merepotkan untuk dipelihara karena sifatnya yang tidak bisa mengetahui posisi setiap tuple indeks secara persis, dan GIN untuk pengindeksan pencarian teks penuh bisa menjadi sangat besar karena kompresibilitas posting tree menurun
Selain itu, dalam situasi memakai index-organized table, saya sulit membayangkan bagaimana padanan BRIN akan diimplementasikan. BRIN memungkinkan rentang besar pada tabel fisik dengan cepat dikeluarkan dari hasil kueri jika tidak ada data yang menarik. Memang bisa dipartisi berdasarkan rentang primary key, tetapi kepadatan nilai primary key dapat sangat bervariasi menurut waktu dan rentang nilai
Saya penasaran bagaimana rencananya mengimplementasikan metode indeks yang lebih kompleks tetapi sangat berguna seperti ini
Ada juga masalah yang bisa muncul ketika aturan pengurutan, yaitu collation, berubah. Karena heap dan VACUUM di Postgres tidak mengetahui urutan sort, setelah perubahan collation kerusakan sering kali dapat diperbaiki dengan menghapus lalu memasukkan kembali baris yang berada di posisi salah, dan membiarkan VACUUM akhirnya membersihkan tuple yang rusak
Pada Oriole, hal itu tampaknya sulit karena tuple asli yang harus dihapus tidak dapat ditemukan dengan point lookup, dan untuk memperbaiki kasus kerusakan indeks yang diketahui kemungkinan diperlukan pembangunan ulang seluruh indeks, sehingga beban pemeliharaannya tampak cukup besar
Pada fungsi mirip GIN, kompresi posting list masih memungkinkan. Salah satu opsi yang mungkin adalah mengaitkan undo record ke seluruh posting list, bukan ke satu item posting list
Karena BRIN memakai index-organized table, sepertinya sulit membuat padanan langsungnya. Namun, union key di halaman internal primary key bisa dimanfaatkan untuk hal-hal menarik
Masalah collation itu benar dan serius. Sebelum GA, semua indeks yang sadar collation perlu dipatok ke versi collation libicu tertentu
Logika artikelnya meyakinkan dan benchmark-nya juga tampaknya mendukung klaim performanya, tetapi saya kurang memahami pemisahan antara storage engine baru yang diusulkan, yaitu OrioleDB, dan PostgreSQL itu sendiri
Selain motivasi komersial dan alasan ingin menghasilkan pendapatan dari inovasi yang dibahas dalam artikel, apakah ada alasan mengapa peningkatan ini harus dipasarkan sebagai database baru bernama OrioleDB alih-alih dikontribusikan ke upstream?
Namun perubahan OrioleDB terlalu besar untuk dimasukkan secara bertahap. Karena itu, perbandingannya adalah antara engine PostgreSQL saat ini, termasuk heap dan berbagai subsistem lain, dengan OrioleDB
Untuk detailnya, lihat terutama slide 9–11 di https://www.socallinuxexpo.org/sites/default/files/presentations/solving-postgres-wicked-problems.pdf
Kalau ini adalah ekstensi engine, saya penasaran apakah ada dampaknya saat digunakan bersama ekstensi lain. Misalnya timescaledb[0] bekerja pada tabel turunan
Saya penasaran apa efeknya jika dilakukan seperti ini
create table xyz(...) using orioledb;select create_hypertable(xyz, ts);[0] https://github.com/timescale/timescaledb
Apakah OrioleDB tertarik menjanjikan format on-disk yang stabil sehingga tidak diperlukan prosedur upgrade antar versi mayor Postgres? Ini tampak seperti peluang untuk menyelesaikan masalah tersebut
Hal-hal seperti penambahan tipe baru beserta fungsi pendukungnya harus disisipkan melalui suatu prosedur upgrade. Ada juga perubahan katalog lain yang mengubah tata letak kolom pada tabel katalog, dan dalam kasus ini juga diperlukan prosedur untuk memperbarui data yang tersimpan antar versi
Tanpa prosedur upgrade, katalog tidak bisa diubah. Karena itu, hanya upgrade versi minor PostgreSQL yang bisa dilakukan cukup dengan mengganti binary dan dapat di-rollback dengan aman tanpa masalah
Jika upgrade dibatasi hanya pada perubahan API internal, planner, dan executor, pengembangan akan sangat terhambat. Sepertinya OrioleDB sulit menghilangkan kebutuhan atas prosedur upgrade ini
Sebagian besar pekerjaan upgrade cluster berasal dari penulisan ulang tabel katalog. Selain itu, untuk sebagian besar workload, pg_upgrade sangat cepat, jadi saya juga kurang melihat dari mana keuntungan besarnya akan muncul
Ungkapan “overhead CPU per transaksi turun 2,3x” terasa mengganjal. Postgres penggunaan CPU-nya naik-turun dari 5% sampai 65%, sedangkan Oriole terus berada di 90%
Prediktabilitasnya memang bagus, tetapi menaikkan rentang rendah sampai 85% bukankah cukup mengkhawatirkan?
Kabar baiknya, ini berarti kalau melakukan scaling vertikal dengan CPU yang lebih kuat, Oriole bisa menghasilkan performa lebih tinggi. Sebaliknya Postgres tidak akan terus meningkat performanya dengan cara yang sama
Dari sudut pandang sistem operasi desktop, waktu idle server Postgres mungkin bisa dipakai untuk hal lain, tetapi di server biasanya kita ingin mesin yang melakukan satu pekerjaan dan dioptimalkan untuk pekerjaan itu
Kalau TPS diturunkan, CPU juga akan turun secara proporsional, dan di sini sepertinya mereka ingin menunjukkan seberapa tinggi batasnya bisa dinaikkan
Jika sistem dibatasi pada CPU 60%, angka totalnya bisa berbeda, tetapi kalau pada penggunaan yang sama TPS-nya 1,8x, itu tetap kemenangan. Ini terlihat seperti angka yang cukup bagus, bukan trik pemasaran
CPU server yang mahal harganya X dolar per unit, tetapi jika hanya bisa dipakai 60% dan secara realistis memang hanya segitu yang bisa dipakai, berarti membakar 0,4X dolar per unit
Jika workload bisa dibawa secara vertikal sampai menjenuhkan 90% satu mesin, umumnya lebih mudah menerapkan QoS dan teknik isolasi untuk mempertahankan tingkat kejenuhan yang lebih rendah dengan performa proporsional. Kebalikannya tidak berlaku. Jika hanya bisa memakai 60% dari kejenuhan penuh mesin dan harus scale-out, untuk mencapai lebih dari 90% perlu desain ulang, dan desain ulang itulah yang terjadi di sini
Disebutkan bahwa sebagai hasil kumulatif dari berbagai perbaikan, OrioleDB menawarkan TPS 5x lebih tinggi, beban CPU per transaksi 2,3x lebih rendah, IOPS per transaksi 22x lebih rendah, serta tanpa bloat pada tabel dan indeks
Beban CPU yang naik-turun bukan berarti Postgres sedang “scaling”, melainkan secara berkala terkena bottleneck performa. Mungkin karena perlu menjalankan VACUUM, dan ini sangat sensitif terhadap I/O
Jadi Postgres memakai I/O untuk pekerjaan bersih-bersih alih-alih memproses query, sehingga TPS dan penggunaan CPU sama-sama anjlok
Sebaliknya Oriole mengelola throughput yang jauh lebih tinggi dengan jauh lebih konsisten. Kalau pedal gas diinjak, mana yang Anda pilih: mobil yang stabil melaju 100 mph, atau mobil yang berayun tajam antara 40–70 mph padahal pedal sudah ditekan sampai mentok?
Di tulisan itu ada tautan dengan judul yang cukup menarik, “10 hal yang dibenci Richard Branson tentang PostgreSQL”. Ternyata orang yang menulis blog itu bukan Richard, melainkan Rick Branson
Oh, ternyata bukan orang itu