Menjamin Transaksi dengan ACID dan MVCC untuk Database Terdistribusi
Bagian ini bergerak ke lapisan transaksional, menjelaskan bagaimana toydb
menyediakan konkurensi dan isolasi untuk operasi database.
Jaminan ACID di Dunia Terdistribusi
Jaminan ACID (Atomicity, Consistency, Isolation, Durability) adalah landasan keandalan database transaksional.
Atomicity: Semua langkah dalam sebuah transaksi berhasil, atau tidak sama sekali. Dalam sistem terdistribusi, ini berarti sebuah transaksi yang mencakup beberapa proposal Raft harus di-commit di semua node yang terlibat atau dibatalkan di mana-mana.
Consistency: Transaksi membawa database dari satu keadaan valid ke keadaan valid lainnya, mempertahankan semua invarian.
Isolation: Transaksi yang berjalan secara konkuren tidak saling mengganggu. Seolah-olah mereka dieksekusi secara serial.
Durability: Setelah sebuah transaksi di-commit, perubahannya bersifat permanen, bahkan jika terjadi kegagalan sistem.
Mempertahankan jaminan ini di banyak node merupakan tantangan yang signifikan.
Paper yang paling sering dikutip yang secara formal mendefinisikan dan mempopulerkan akronim ACID adalah karya dari Andreas Reuter dan Theo Härder1. Meskipun konsep-konsepnya sudah ada sebelumnya (terutama dari karya Jim Gray), paper ini mengkristalkannya menjadi empat properti yang kita kenal sekarang.
Masalah Konkurensi: Mengapa Isolasi Penting
Ketika beberapa transaksi berjalan secara bersamaan, mereka dapat saling mengganggu dengan cara yang tidak diinginkan, yang mengarah pada anomali seperti:
Dirty Reads: Sebuah transaksi membaca data yang telah ditulis oleh transaksi lain yang belum di-commit.
Non-repeatable Reads: Sebuah transaksi membaca baris yang sama dua kali dan mendapatkan nilai yang berbeda karena transaksi lain memodifikasinya di antara pembacaan.
Phantom Reads: Sebuah transaksi menjalankan kueri yang sama dua kali dan mendapatkan set baris yang berbeda karena transaksi lain menyisipkan atau menghapus baris.
Solusi tradisional untuk masalah ini adalah penguncian (locking), di mana sebuah transaksi mengunci data yang diaksesnya untuk mencegah transaksi lain memodifikasinya. Namun, penguncian dapat secara drastis mengurangi performa dan menyebabkan deadlock.
Penjelasan Multi-Version Concurrency Control (MVCC)
Multi-Version Concurrency Control (MVCC) adalah mekanisme kontrol konkurensi canggih yang digunakan oleh banyak database modern, termasuk toydb
, untuk memberikan isolasi tanpa biaya performa dari penguncian yang ketat. Prinsip intinya adalah “operasi baca tidak pernah memblokir operasi tulis, dan operasi tulis tidak pernah memblokir operasi baca”.
Alih-alih menimpa data saat pembaruan, MVCC membuat versi baru dari item data tersebut. Setiap versi ditandai dengan informasi yang mengidentifikasi transaksi yang membuatnya.
Snapshot Isolation: Setiap transaksi diberi timestamp saat dimulai. Ketika transaksi membaca data, ia melihat “snapshot” yang konsisten dari database seperti pada saat timestamp tersebut. Ia hanya melihat versi data yang telah di-commit sebelum transaksi dimulai.
Aturan Visibilitas: Aturan yang jelas, berdasarkan timestamp transaksi dan timestamp versi data, menentukan versi mana dari sebuah item data yang “terlihat” oleh transaksi tertentu.
Operasi Tulis: Ketika sebuah transaksi menulis data, ia membuat versi baru dari item data tersebut, yang ditandai dengan timestamp transaksi itu sendiri. Versi baru ini tidak akan terlihat oleh transaksi lain sampai transaksi penulis di-commit.
MVCC adalah teknologi kritis yang memungkinkan database SQL terdistribusi modern menawarkan konsistensi yang kuat (ACID) tanpa mengorbankan konkurensi tinggi yang diperlukan untuk beban kerja OLTP. Ini menyelesaikan ketegangan fundamental antara isolasi dan performa.
Konsep Multi-Version Concurrency Control (MVCC) diperkenalkan dalam disertasi Ph.D. David P. Reed2 di MIT. Karya ini meletakkan dasar teoretis untuk sistem yang mengelola konkurensi dengan mempertahankan beberapa versi data, yang memungkinkan operasi baca untuk berjalan tanpa memblokir operasi tulis.
Implementasi MVCC di toydb
bukan hanya sebuah fitur; ini adalah demonstrasi model kontrol konkurensi inti yang membuat sistem seperti CockroachDB, TiDB, dan PostgreSQL berkinerja tinggi di bawah beban kerja yang konkuren.
Penelusuran Kode: MVCC di toydb
Implementasi MVCC di toydb
berada di toydb
berada di src/storage/mvcc.rs
.
Skema Pengkodean Kunci: File
mvcc.rs
membungkus storage engine di bawahnya dan menggunakan skema pengkodean yang menggabungkan kunci asli dengan timestamp (versi) untuk setiap entri. Kunci di storage engine tidak hanya berupa kunci pengguna. Kunci tersebut dimodifikasi untuk menyertakan informasi versi, biasanya sebuah timestamp. Misalnya, kunciuser:123
mungkin disimpan sebagaiuser:123:<timestamp>
.Operasi Baca (Get): Logika
get
di dalammvcc.rs
melakukan pencarian untuk menemukan versi kunci yang tepat yang terlihat oleh snapshot transaksi saat ini (yaitu, versi terbaru dengan timestamp yang lebih kecil dari timestamp transaksi). Ketika sebuah transaksi dengan timestamp Ts membaca kunciuser:123
, storage engine akan memindai semua versi untuk kunci tersebut dan mengembalikan nilai dari versi dengan timestamp terbaru yang lebih kecil dari Ts.Operasi Tulis (Set): Logika
set
dimvcc.rs
tidak menimpa data, melainkan membuat versi baru dari kunci dengan timestamp transaksi yang sedang berjalan, yang kemudian ditulis ke storage engine. Ketika sebuah transaksi menulis ke kunciuser:123
, ia tidak menimpa nilai yang ada. Sebaliknya, ia menyisipkan entri baru,user:123:<timestamp_commit>
, di mana<timestamp_commit>
adalah timestamp saat transaksi di-commit.
Reuter, A., & Härder, T. (1983). Principles of Transaction-Oriented Database Recovery. ACM Computing Surveys. Diakses pada 5 Oktober 2025.
Reed, D. P. (1981). Implementing Atomic Actions On Decentralized Data. (Ph.D. Thesis). Massachusetts Institute of Technology. Diakses pada 5 Oktober 2025.