4 poin oleh GN⁺ 2024-10-21 | 1 komentar | Bagikan ke WhatsApp
  • PostgreSQL belakangan muncul sebagai pilihan default di internet, tetapi menurut pengalaman Carnegie Mellon dan OtterTune, implementasi MVCC-nya membawa beban operasional yang lebih besar dibanding MySQL, Oracle, dan Microsoft SQL Server
  • Inti desainnya adalah penyimpanan append-only yang membuat versi fisik baru alih-alih menimpa baris lama saat sebuah baris diperbarui, serta rantai O2N yang menelusuri dari versi lama ke versi baru
  • Struktur ini menyebabkan penyalinan seluruh tuple, akumulasi dead tuple, pembaruan semua indeks, dan ketergantungan pada autovacuum; sebagian biaya hanya bisa dihindari jika HOT update memungkinkan
  • Dalam analisis PostgreSQL milik pelanggan OtterTune, rata-rata hanya sekitar 46% pembaruan yang menggunakan optimisasi HOT, dan pengaturan autovacuum bawaan bisa terlalu lama menunda pembersihan pada tabel besar
  • PostgreSQL tetap DBMS yang menarik, tetapi pada workload dengan banyak penulisan dan tabel besar, Anda harus mengelola sendiri ruang penyimpanan, I/O, memori, perawatan indeks, dan operasi vacuum

Mengapa MVCC PostgreSQL Menjadi Masalah

  • Pilihan database sangat banyak; per April 2023, DBDB mencatat 897 di antaranya, tetapi pada tiap era selalu ada pilihan default de facto
    • Pada 2000-an, MySQL yang dipakai Google dan Facebook menjadi pilihan yang lazim
    • Pada 2010-an, MongoDB menarik perhatian dengan citra “webscale”-nya
    • Dalam 5 tahun terakhir, PostgreSQL banyak dipilih karena stabilitas, fitur yang kaya, ekstensibilitas, dan kecocokannya untuk workload operasional
  • Fokus tulisan ini adalah implementasi multi-version concurrency control (MVCC) di PostgreSQL
    • Berdasarkan riset Carnegie Mellon dan pengalaman mengoptimalkan Amazon RDS PostgreSQL, implementasi MVCC PostgreSQL dinilai lebih buruk daripada MySQL, Oracle, dan Microsoft SQL Server
    • Amazon Aurora PostgreSQL juga memiliki masalah struktural yang sama

Tujuan MVCC dan Pilihan Desain PostgreSQL

  • MVCC adalah pendekatan untuk memungkinkan banyak kueri membaca dan menulis database secara bersamaan tanpa saling mengganggu bila memungkinkan
    • DBMS menyimpan beberapa versi fisik untuk setiap baris logis alih-alih menimpa baris yang ada
    • Kueri membaca versi yang sesuai untuknya berdasarkan urutan versi seperti waktu pembuatannya
    • Ini memungkinkan snapshot isolation, yaitu melihat snapshot database pada saat transaksi dimulai
  • Operasi baca dapat mengurangi situasi ketika terhalang explicit record lock akibat operasi tulis yang memperbarui item yang sama
  • DBMS berbasis MVCC pada dasarnya harus menentukan tiga hal
    • bagaimana menyimpan pembaruan pada baris yang ada
    • bagaimana menemukan versi baris yang sesuai untuk kueri saat runtime
    • bagaimana menghapus versi kedaluwarsa yang sudah tidak terlihat lagi
  • Karena pilihan pertama yang diambil PostgreSQL pada 1980-an, beban pada dua area lainnya masih terbawa sampai sekarang

Penyimpanan Versi Append-Only

  • PostgreSQL sejak awal dirancang untuk mendukung multi-version; saat pembaruan, ia tidak menimpa baris lama, melainkan membuat salinan lalu menerapkan perubahan pada versi baru
  • Pendekatan ini bisa dipandang sebagai penyimpanan versi append-only
    • Saat tuple yang ada diperbarui, DBMS menyiapkan slot kosong di tabel untuk versi baris yang baru
    • Isi baris versi saat ini disalin ke versi baru
    • Perubahan diterapkan pada slot versi yang baru dialokasikan
  • Tabel contoh adalah tabel movies yang menyimpan informasi film
    • id adalah primary key, dengan kolom name, year, dan director
    • Ada indeks primer movies_pkey serta indeks sekunder B+Tree idx_name dan idx_director
  • Dalam pembaruan yang mengubah tahun rilis "Shaolin and Wu Tang" dari 1985 menjadi 1983, tuple asli disalin lebih dulu lalu tahun yang berubah diterapkan pada versi baru
    • Jika tidak ada ruang pada page yang ada, versi baru bisa dibuat di page tabel yang berbeda

Rantai Versi dan Skema O2N

  • Jika beberapa versi fisik mewakili satu baris logis yang sama, DBMS harus mencatat hubungan antarversi
    • DBMS MVCC membuat rantai versi dalam bentuk linked list satu arah
    • Rantai dibuat searah untuk mengurangi biaya penyimpanan dan pemeliharaan
  • Ada dua urutan rantai versi
    • N2O: versi terbaru menunjuk ke versi sebelumnya, dan kepala rantai selalu versi terbaru
    • O2N: setiap versi menunjuk ke versi yang lebih baru, dan kepala rantai adalah versi tertua
  • Sebagian besar DBMS, termasuk Oracle dan MySQL, mengimplementasikan N2O
  • PostgreSQL termasuk jarang memakai O2N, selain engine In-Memory OLTP milik Microsoft SQL Server
    • O2N dapat mengurangi kebutuhan memperbarui indeks agar menunjuk ke versi baru setiap kali tuple dimodifikasi
    • Sebagai gantinya, sistem mungkin harus menelusuri rantai versi yang panjang untuk menemukan versi terbaru
  • Field t_tcid pada header baris PostgreSQL menyimpan tuple ID versi berikutnya, atau tuple ID dirinya sendiri jika itu versi terbaru
    • Jika indeks menunjuk ke versi lama, PostgreSQL harus mengikuti rantai untuk menemukan versi yang baru

Cara Mengurangi Penelusuran Rantai dengan Indeks

  • Sejak awal, para pengembang PostgreSQL sudah mengetahui dua biaya berikut
    • biaya membuat salinan penuh tuple baru pada setiap pembaruan sangat besar
    • sia-sia jika sebagian besar kueri harus menelusuri seluruh rantai versi untuk menemukan versi terbaru yang diinginkan
  • Untuk menghindari penelusuran rantai yang panjang, PostgreSQL menambahkan entri indeks untuk setiap versi fisik dari suatu baris
    • Jika satu baris logis memiliki 5 versi fisik, bisa ada hingga 5 entri indeks untuk tuple tersebut
    • Jika indeks idx_name menunjuk ke beberapa versi "Shaolin and Wu Tang", PostgreSQL bisa langsung mengakses versi terbaru
  • Akses ke versi terbaru bisa menjadi lebih cepat, tetapi indeks membesar dan biaya pemeliharaannya meningkat

Optimisasi HOT Update

  • PostgreSQL menggunakan HOT (heap-only tuple) update untuk mengurangi situasi ketika versi terkait tersebar di banyak page dan menimbulkan banyak entri indeks
  • Ada dua syarat agar HOT update bisa digunakan
    • pembaruan tidak mengubah kolom yang dirujuk oleh indeks tabel
    • ada cukup ruang agar versi baru dapat disimpan pada page data yang sama dengan versi sebelumnya
  • Jika HOT diterapkan, indeks tetap menunjuk ke versi lama, dan kueri menemukan versi terbaru dengan mengikuti rantai versi
  • PostgreSQL juga melakukan optimisasi untuk memangkas rantai versi dengan menghapus versi lama selama operasi normal

Penghapusan Dead Tuple dan Vacuum

  • Karena PostgreSQL membuat salinan baris setiap kali melakukan pembaruan, versi lama berupa dead tuple harus dihapus
  • PostgreSQL awal pada 1980-an tidak menghapus dead tuple
    • Gagasannya adalah bahwa mempertahankan versi lama memungkinkan kueri time-travel yang melihat status database pada titik waktu tertentu
    • Tetapi tanpa penghapusan dead tuple, ukuran tabel tidak menyusut walau ada penghapusan, dan rantai versi untuk tuple yang sering diperbarui menjadi panjang
  • PostgreSQL membersihkan dead tuple dari tabel melalui prosedur vacuum
    • vacuum melakukan sequential scan pada page tabel yang telah dimodifikasi sejak eksekusi terakhir dan mencari versi yang kedaluwarsa
    • Sebuah versi dianggap expired jika tidak terlihat oleh transaksi aktif mana pun
    • Karena transaksi saat ini tidak akan mengakses versi itu dan transaksi mendatang akan menggunakan versi live terbaru, ruangnya aman untuk digunakan kembali
  • PostgreSQL dapat menjalankan autovacuum secara berkala sesuai konfigurasi
    • Frekuensi vacuum untuk seluruh tabel dapat disesuaikan lewat pengaturan global
    • Pengaturan autovacuum per tabel juga dimungkinkan
    • Pengguna juga dapat menjalankannya secara manual dengan perintah SQL VACUUM

Masalah 1: Penyalinan Seluruh Tuple

  • Dalam MVCC append-only, meskipun hanya satu kolom tuple yang berubah, semua kolom tetap disalin ke versi baru
  • Pendekatan ini sangat meningkatkan duplikasi data dan kebutuhan ruang penyimpanan
    • PostgreSQL bisa membutuhkan lebih banyak memori dan disk untuk menyimpan database yang sama dibanding DBMS lain
    • Akibatnya, kueri bisa melambat dan biaya cloud dapat meningkat
  • MySQL dan Oracle menyimpan delta terkompresi antara versi baru dan versi saat ini
    • Dalam tabel dengan 1000 kolom, jika hanya satu kolom yang berubah, hanya delta record untuk satu kolom yang berubah itu yang disimpan
    • PostgreSQL membuat versi baru yang berisi satu kolom yang berubah dan 999 kolom lain yang tidak berubah
  • Properti TOAST PostgreSQL diperlakukan berbeda sehingga dikecualikan dari perbandingan ini
  • Pada 2013, EnterpriseDB memulai proyek zheap untuk mengubah storage engine append-only menjadi berbasis versi delta
    • Pembaruan resmi terakhir adalah status post pada 2021
    • Setelah itu, tidak terlihat kemajuan yang jelas

Masalah 2: Table Bloat

  • Versi kedaluwarsa PostgreSQL, yaitu dead tuple, memakan ruang lebih besar daripada versi delta
  • Pada workload yang write-heavy, dead tuple dapat menumpuk lebih cepat daripada kemampuan autovacuum mengejarnya
    • Tabel bisa terus membesar
    • Karena dead tuple dan live tuple bercampur di dalam page, kueri juga harus memuat dead tuple ke memori saat eksekusi
    • Bloat yang tidak terkendali meningkatkan konsumsi IOPS dan memori saat table scan, sehingga menurunkan performa kueri
    • Jika dead tuple membuat statistik optimizer menjadi tidak akurat, hasilnya bisa berupa query plan yang buruk
  • Sebagai contoh, jika tabel movies memiliki 10 juta live tuple dan 40 juta dead tuple, maka 80% isinya adalah data usang
    • Jika ukuran rata-rata tuple adalah 1KB, live tuple memakan 10GB dan dead tuple sekitar 40GB
    • Ukuran total tabel menjadi 50GB
    • Saat full table scan, PostgreSQL tetap harus membaca 50GB dari disk dan memuatnya ke memori, meskipun sebagian besar adalah data usang
  • PostgreSQL memang memiliki mekanisme perlindungan agar sequential scan tidak mencemari cache buffer pool, tetapi itu tidak menghilangkan biaya I/O-nya sendiri

Perbedaan VACUUM dan VACUUM FULL

  • Walaupun autovacuum berjalan berkala dan mampu mengikuti workload, autovacuum biasa tetap tidak dapat mengembalikan ruang penyimpanan ke sistem operasi
  • VACUUM biasa menghapus dead tuple dan menata ulang live tuple di dalam tiap page, tetapi tidak merebut kembali page kosong di disk
  • Jika PostgreSQL bisa mengosongkan page terakhir, page itu dapat dipangkas, tetapi page lain tetap berada di disk
    • Bahkan setelah menghapus 40GB dead tuple dari tabel 50GB, PostgreSQL mungkin tetap mempertahankan alokasi 50GB dari sudut pandang sistem operasi atau RDS
  • Untuk benar-benar mengembalikan ruang yang tidak terpakai, seluruh tabel harus ditulis ulang ke ruang baru menggunakan VACUUM FULL atau pg_repack
    • Keduanya memakan banyak sumber daya dan waktu lama
    • Pada database produksi, dampaknya bisa besar terhadap performa kueri
  • VACUUM FULL menghapus dead tuple dari setiap page, memadatkan live tuple yang tersisa ke page baru, lalu menghapus page yang tidak lagi diperlukan

Masalah 3: Pemeliharaan Indeks Sekunder

  • PostgreSQL harus memperbarui semua indeks pada tabel ketika satu tuple diperbarui
  • Ini karena indeks primer maupun indeks sekunder menyimpan lokasi fisik yang tepat dari suatu versi
    • Kecuali pada HOT update di mana versi baru disimpan pada page yang sama dengan versi sebelumnya, pekerjaan ini diperlukan pada setiap pembaruan
  • Pada contoh pembaruan, PostgreSQL membuat versi baru di Table Page #2, lalu memasukkan entri yang menunjuk ke versi baru tersebut ke movies_pkey, idx_director, dan idx_name
  • Struktur yang mengharuskan modifikasi semua indeks ini menimbulkan banyak biaya performa
    • kueri pembaruan menjadi lebih lambat
    • ada I/O tambahan untuk menelusuri tiap indeks dan menyisipkan entri baru
    • muncul kontensi lock/latch pada indeks dan struktur internal seperti page table buffer pool
    • biaya pemeliharaan juga dibayar untuk indeks yang sebenarnya tidak dipakai kueri aktual
    • pada DBMS dengan penagihan berbasis IOPS seperti Amazon Aurora, pembacaan dan penulisan tambahan menjadi masalah
  • Dalam analisis database PostgreSQL pelanggan OtterTune, rata-rata sekitar 46% pembaruan menggunakan optimisasi HOT
    • Artinya, lebih dari 50% pembaruan sisanya tetap menanggung biaya pemeliharaan indeks
  • Tulisan Uber tahun 2016 tentang migrasi dari Postgres ke MySQL adalah contoh representatif masalah ini
    • Pada tabel dengan banyak indeks sekunder, workload write-heavy mengalami masalah performa yang besar
  • Oracle dan MySQL tidak memiliki masalah yang sama karena indeks sekunder mereka tidak menyimpan alamat fisik versi baru
    • Indeks sekunder menyimpan pengenal logis seperti tuple ID atau primary key
    • DBMS menggunakan pengenal logis itu untuk menemukan alamat fisik versi saat ini
    • Pembacaan indeks sekunder bisa lebih lambat, tetapi overhead berkurang berkat keuntungan lain dari implementasi MVCC mereka

Masalah 4: Sulitnya Operasi Autovacuum

  • Performa PostgreSQL sangat bergantung pada efektivitas autovacuum untuk membuang data usang dan memungkinkan ruang dipakai ulang
  • Karena RDS, Aurora, dan Aurora Serverless semuanya merupakan varian PostgreSQL, semuanya memiliki masalah autovacuum yang sama
  • autovacuum itu kompleks sehingga sulit dijalankan dalam kondisi optimal
    • pengaturan bawaan tidak cocok untuk semua tabel
    • masalah ini makin besar terutama pada tabel berukuran besar
  • Nilai default autovacuum_vacuum_scale_factor adalah 20%
    • Pada tabel dengan 100 juta tuple, setidaknya 20 juta tuple harus diperbarui sebelum autovacuum terpicu
    • Akibatnya, banyak dead tuple bisa lama tertinggal di tabel dan menimbulkan biaya I/O serta memori
  • long-running transaction dapat menghalangi autovacuum
    • Jika pembersihan expired version tertunda, dead tuple dan statistik lama akan menumpuk
    • Masalah performa dapat memunculkan lebih banyak long-running transaction, dan transaksi itu lagi-lagi menghalangi autovacuum, menciptakan lingkaran setan
    • Dalam situasi seperti ini, manusia mungkin harus menghentikan long-running transaction secara manual

Kasus Pelanggan OtterTune

  • Pada satu database PostgreSQL Amazon RDS, jumlah dead tuple berubah dengan pola seperti gigi gergaji selama dua minggu
    • autovacuum melakukan pembersihan besar sekitar sekali sehari
    • Pada 14 Februari, DBMS membersihkan 3,2 juta dead tuple
    • Secara keseluruhan di grafik, jumlah dead tuple menunjukkan tren naik, yang berarti autovacuum tidak mampu mengejar dan sistem berada dalam kondisi tidak sehat
  • Pada sebuah instance PostgreSQL RDS milik pelanggan OtterTune, terjadi long-running query setelah bulk insertion karena statistik yang sudah usang
    • Kueri ini menghalangi pembaruan statistik oleh autovacuum
    • Akibatnya, lebih banyak long-running query pun muncul
    • Health check otomatis OtterTune berhasil mengidentifikasi masalah ini, tetapi administrator tetap harus menghentikan kueri secara manual dan menjalankan ANALYZE setelah bulk insertion
    • Waktu eksekusi long query tersebut turun dari 52 menit menjadi 34 detik

Kesimpulan Praktis

  • Dalam desain DBMS, selalu ada pilihan-pilihan sulit, dan pilihan itu memengaruhi performa pada workload yang berbeda
  • Pada workload tertentu yang write-intensive di Uber, write amplification pada indeks akibat MVCC PostgreSQL menjadi alasan berpindah ke MySQL
  • Implementasi MVCC PostgreSQL dinilai sebagai pendekatan yang sebaiknya tidak ditiru jika membangun DBMS MVCC baru
    • kombinasi penyimpanan append-only dan autovacuum adalah masalah utamanya
    • desain ini adalah warisan 1980-an, dari masa sebelum pola sistem log-structured menyebar luas sejak 1990-an
  • PostgreSQL tetap merupakan DBMS yang disukai, tetapi penggunaannya harus menerima dan mengelola kelemahan MVCC tersebut
  • Jalan keluarnya adalah menaruh banyak waktu dan usaha sendiri untuk melakukan tuning

1 komentar

 
GN⁺ 2024-10-21
Komentar Hacker News
  • Saya merasa cukup memahami bagian internal Postgres, tetapi tulisan ini sangat bagus dan saya banyak belajar
    Salah satu kelemahan mendasarnya tampaknya adalah Postgres memilih pendekatan O2N, bukan N2O, untuk pelacakan versi baris. Mengubahnya ke N2O tidak akan menyelesaikan semua masalah; misalnya masalah menyimpan salinan penuh baris tetap ada. Namun dari sudut pandang 80/20, sepertinya itu bisa mengurangi sebagian besar kekurangan implementasi saat ini
    Sebagian besar transaksi akan menginginkan versi baris terbaru, jadi dengan memakai urutan N2O, kita hanya perlu mengikuti linked list ketika membutuhkan versi lama, dan besar kemungkinan tidak perlu menyimpan setiap versi baris di indeks

    • Sebaiknya tonton kuliah YouTube Andy, History of Databases (CMU Databases / Spring 2020)
      Seluruh kelas pertamanya ia bawakan di jalanan Amsterdam karena tidak bisa masuk ke hotel; karakternya menarik dan kemampuannya menjelaskan cara kerja internal luar biasa
  • Keuntungan besarnya adalah ketika beban kerja terutama terdiri dari INSERT lalu penghapusan tabel setelahnya, tidak diperlukan ruang tambahan
    Biasanya transaksi insert juga tidak perlu dipecah. Sebab pada praktiknya tidak ada batasan nyata pada ukuran data yang dibuat atau jumlah total baris yang diubah. Ada batas jumlah statement dalam transaksi, tetapi jika tidak terlalu sering mengubah tabel, itu bisa diakali dengan COPY FROM
    Dari sudut pandang DBA, tidak perlu mengelola ruang rollback/undo secara terpisah dari penyimpanan tabel. Bergantung aplikasinya, tetapi desain PostgreSQL bukan pecundang di semua aspek. Maksudnya, ini bukan seperti bubble sort

    • Saat mengembangkan game pada awal 2000-an, saya belajar bahwa bubble sort pun bukan pecundang di semua aspek
      Performanya bagus ketika daftar hampir terurut, dan itu terjadi dalam rendering 3D saat mengurutkan objek berdasarkan jaraknya dari kamera. Jika kamera sedikit digeser atau diputar, bubble sort bekerja sangat baik ketika mengurutkan ulang berdasarkan urutan dari frame sebelumnya
      Untuk menghindari kasus terburuk, cukup hitung jumlah perbandingan yang gagal pada pass terakhir dan jumlah pass yang sudah dilakukan; jika melewati ambang tertentu, beralihlah ke algoritma pengurutan lain
    • Bubble sort sangat bagus pada hardware atau himpunan yang hampir terurut
    • Tulisan itu secara harfiah mengatakan desain MVCC pg bergaya tahun 90-an dan sekarang tidak ada lagi yang melakukannya seperti itu
      Karena ini teknologi yang sudah usang lebih dari 30 tahun, meski mungkin bukan pecundang di semua aspek, menurut saya ia pecundang pada aspek yang paling penting
  • Menurut saya tulisan ini keliru terutama pada bagian berikut
    “Pada 2000-an, kebijaksanaan umum memilih MySQL karena bintang-bintang teknologi yang sedang naik daun seperti Google dan Facebook menggunakannya. Pada 2010-an, giliran MongoDB yang menjadi ‘webscale’ berkat penulisan yang tidak durable. Dalam lima tahun terakhir, PostgreSQL menjadi DBMS kesayangan internet. Ada alasan bagus untuk itu! Ia andal, kaya fitur, dapat diperluas, dan cocok untuk sebagian besar beban kerja operasional.”
    Para engineer pintar memilih Postgres bukan karena fallacy appeal to popularity, melainkan karena keamanan data, ACID, kemiripan dengan Oracle, MVCC, kepatuhan pada standar SQL, tim Postgres, komunitas yang hebat dan membantu, tipe data, performa tinggi, serta fleksibilitas BSD
    Hal-hal itulah juga alasan ATT memilih Postgres pada awal 2000-an, dan DBA Oracle pun menerima transisinya dengan sangat mudah. Sementara MySQL mengalami transisi yang berat, PG terus menguat dan membaik. Saya rasa Bruce Momjian berperan besar dalam kesuksesan ini, dan komunitasnya benar-benar luar biasa

    • Serupa dengan itu, pada 2005 preferensi saya beralih dari MySQL ke PostgreSQL
      Alasannya, saya ingin memakai view database untuk membuat lapisan kompatibilitas “live” antara skema database AS400 lama dan aplikasi Rails modern
      Setelah itu, preferensi tersebut terus menguat berkat keamanan data, DDL di dalam transaksi, dan hal-hal semacamnya
  • “MySQL dan Oracle menyimpan delta terkompresi antara versi baru dan versi saat ini (anggap seperti git diff).”
    Bukankah Git terkenal tidak menyimpan diff, melainkan menyimpan objek baru dan seluruh objek sebelumnya, seperti cara yang dipakai Postgres di sini?

    • Kalimat yang dikutip bukan mengatakan Git menyimpan diff, melainkan bahwa yang disimpan MySQL dan Oracle mirip git diff
    • Benar. Setiap versi file adalah blob terpisah
      Memang ada kompresi lewat packing agar clone lebih cepat, tetapi bentuk mentah yang ditangani Git adalah blob-blob seperti itu
    • Perbandingannya bukan dengan cara Git menyimpan data, melainkan analogi bahwa cara penyimpanan MySQL dan Oracle mirip dengan format git diff
      Repository Git juga melakukan kompresi, dan kompresi itu semacam berbasis diff, tetapi bukan berbasis riwayat commit seperti dugaan naif
    • Saya menyebut bahwa orang lain mengatakan “git diffs”, tetapi Git memang memakai delta sebagai optimisasi level rendah di pack file, dan itu mirip dengan perbandingan MySQL
      Dalam query SQL pun diff tidak dikembalikan apa adanya
    • Git diff dibuat secara spontan, tetapi diff tetaplah diff
  • “Kebutuhan PostgreSQL untuk memodifikasi semua indeks tabel pada setiap update menimbulkan beberapa dampak performa. Tentu saja, karena sistem harus melakukan lebih banyak pekerjaan, query update menjadi lebih lambat.”
    Saya penasaran soal write amplification ini. Benar bahwa MySQL tidak perlu memperbarui indeks dengan cara seperti itu, tetapi replikasi MySQL bergantung pada binlog, dan semua perubahan harus dicatat lagi selain di database itu sendiri (InnoDB redo log, dll.)
    Jadi MySQL yang dipakai dalam cluster tampaknya memiliki write amplification jenis lain. PostgreSQL menggunakan kembali WAL untuk replikasi, sehingga tidak ada amplifikasi seperti itu
    Selain itu, di sisi penerima, MySQL pertama-tama menulis binlog yang masuk ke relay log, lalu relay log dikonsumsi oleh thread applier yang menghasilkan penulisan InnoDB tambahan dan, dengan konfigurasi default, binlog tambahan

  • Topik ini tidak bisa dibahas tanpa membicarakan disk
    SSD menulis halaman 4KB sekaligus. Artinya, meski hanya memperbarui 1 bit, disk akan membaca 4KB, mengubah bit tersebut, lalu menulis ulang halaman 4KB ke slot baru. Jadi penalti penyalinan bergantung pada jenis disk

    • Menarik. Saya penasaran bagaimana ini tercermin dalam penagihan AWS
      AWS mengenakan biaya tetap untuk MBps I/O, tetapi saya tidak tahu apakah ada aturan pembulatan ke 4KB terdekat, atau apakah mereka melacak volume tulis drive itu sendiri, bukan jumlah request, lalu menagih jumlah I/O aktual pada implementasi storage
    • Halaman Postgres berukuran 8KB, jadi poin itu tidak terlalu berarti
  • “Oracle dan MySQL tidak memiliki masalah ini dalam implementasi MVCC mereka. Sebab, indeks sekunder tidak menyimpan alamat fisik versi baru. Sebagai gantinya, mereka menyimpan identifier logis (misalnya tuple ID, primary key), dan DBMS menggunakannya untuk menemukan alamat fisik versi saat ini. Karena itu pembacaan indeks sekunder bisa menjadi lebih lambat, tetapi DBMS ini punya keunggulan lain dalam implementasi MVCC yang mengurangi overhead.”
    Ada perilaku menarik yang saya amati di MySQL. Database-nya sekitar 500GB dan skemanya lebih mirip document-oriented daripada relasional; SELECT id WHERE something; UPDATE what WHERE id=id beberapa orde magnitudo lebih cepat daripada UPDATE what WHERE something
    Saya menduga alasan perilaku ini mungkin ada di sini. Namun workload biasa tidak melakukannya seperti ini, dan hanya menjadi lambat pada DML sementara untuk memperbaiki inkonsistensi

    • SELECT adalah operasi read-only, jadi bisa dijalankan secara paralel
      Sebaliknya, UPDATE benar-benar melakukan penulisan dan mungkin mengunci tabel. UPDATE id=id memungkinkan penguncian tingkat baris. Namun ada juga risiko melewatkan record yang baru disisipkan di antara SELECT dan UPDATE
    • Saya mengoperasikan beberapa instance Postgres yang dominan baca dan berukuran lebih dari 2TB, dan ini juga lebih mirip document-oriented
      Saya setuju bahwa update massal bisa sangat lambat. Pada akhirnya, kami sering memproses update secara bertahap per batch atau bahkan memakai COPY
  • “Pada 2010-an, itu adalah MongoDB. Karena penulisan yang tidak durable membuatnya menjadi ‘webscale’.”
    Agak keluar dari topik, tetapi sejak awal hingga akhir itu adalah marketing: https://news.ycombinator.com/item?id=15124306

    • MongoDB dirancang sebagai DB DIY yang dibuat sambil lalu oleh para mantan engineer DoubleClick karena tidak ada DB yang memenuhi kebutuhan yang diperlukan untuk layanan lain
      Versi 4.2.8 (2020) sudah cukup solid, dan diketahui tidak memiliki dirty write: https://en.wikipedia.org/wiki/MongoDB#Technical_criticisms
  • Hal yang paling saya benci adalah bahkan pada 2024, agar layak dipakai, kita masih harus menaruh connection pooler (misalnya pgbouncer) di depannya

  • OrioleDB pernah mencoba menyelesaikan masalah ini dengan storage engine baru: https://github.com/orioledb/orioledb

    • Ada di tim Supabase
      Oriole kini telah bergabung dengan Supabase, dan Alexander beserta timnya mengerjakannya secara penuh waktu. Patch set-nya ada di sini: https://www.orioledb.com/docs#patch-set
      Kemungkinan akan bisa dicoba juga di platform Supabase pada akhir tahun ini