Topik ini memperkenalkan Mnesia, basis data transaksional milik OTP yang menyimpan data Erlang apa adanya dan menyebarnya ke beberapa node: pembuatan skema, tabel, transaksi, serta baca cepat tanpa transaksi. Mnesia juga punya sisi yang perlu diwaspadai sejak awal, karena kesesuaiannya selalu dipertanyakan dibanding basis data eksternal.
Posisi Mnesia di ekosistem#
Mnesia lahir dari kebutuhan Erlang sendiri: data yang bentuknya persis data Erlang, transaksional, dan tersebar di node-node VM tanpa penerjemahan skema ke bahasa lain. Ia menyimpan record Erlang, memakai fungsi Erlang sebagai query, dan menuntut setiap node dalam klaster mengetahui skemanya. Karena itulah Mnesia paling nyaman pada data ukuran sedang yang benar-benar hidup di klaster Erlang, misalnya sesi pengguna atau katalog konfigurasi. Pada data besar, data yang harus dibaca aplikasi lain, atau data yang menuntut alat administrasi matang, basis data eksternal biasanya pilihan yang lebih tepat, dan keputusan ini perlu dibuat di awal, bukan setelah data tumbuh.
Skema, tabel, dan transaksi#
Mnesia menyimpan skema di disk node dan tabelnya bisa di memori, di disk, atau keduanya. Siklus pertama berikut membuat skema, menyalakan Mnesia, membuat tabel, lalu menulis dan membaca lewat transaksi:
Erlang/OTP 29 [erts-17.1.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]
Eshell V17.1.1 (press Ctrl+G to abort, type help(). for help)
1> mnesia:create_schema([node()]).
{ok,[nonode@nohost]}
2> mnesia:start().
ok
3> mnesia:create_table(siswa, [{attributes, [nama, nilai]}]).
{atomic,ok}
4> mnesia:transaction(fun() -> mnesia:write({siswa, "Ali", 90}) end).
{atomic,ok}
5> mnesia:transaction(fun() -> mnesia:read({siswa, "Ali"}) end).
{atomic,[{siswa,"Ali",90}]}create_schema/1 harus dijalankan saat Mnesia belum berjalan dan menulis folder skema di folder kerja. create_table/2 menyatakan nama record dan daftar bidangnya, dan operasi write/1 beserta read/1 hanya sah di dalam transaction/1, yang kembaliannya dibungkus atom atomic bila sukses. Transaksi Mnesia memiliki semantik ACID pada klaster node yang berbagi skema, dan kegagalan di tengah jalan membuat seluruhnya dibatalkan.
Inspeksi tabel dan salinan disk#
Tabel yang berjalan dapat diperiksa lewat table_info/2, dan lokasi penyimpanan dipilih saat create_table/2:
4> mnesia:transaction(fun() -> mnesia:write({siswa, "Ali", 90}) end).
{atomic,ok}
5> mnesia:table_info(siswa, size).
1Pembacaan size mengembalikan satu, sesuai satu baris yang ditulis. Opsi {disc_copies, [node()]} pada pembuatan tabel membuat barisnya hidup di memori sekaligus ditulis ke disk, sehingga VM yang mati tidak menghapusnya, sedangkan {ram_copies, [node()]} bawaan hanya menyimpan di memori dan {disc_only_copies, [node()]} menyimpan di disk saja dengan akses yang lebih lambat. Tabel yang hanya di memori dan skema yang di disk adalah pasangan yang paling sering dipakai: data panas dibaca cepat, sedangkan bentuk tabelnya tetap tahan terhadap kehilangan.
Distribusi Mnesia berpangkal pada skema yang disebarkan ke beberapa node dengan create_schema/1 yang menerima daftar node tersebut. Tabel dengan disc_copies pada beberapa node direplikasi oleh Mnesia sendiri, dan transaksi menulis ke seluruh salinan secara atomik. Desain ini menghilangkan satu lapisan infrastruktur yang biasanya ditangani basis data eksternal, sekaligus memindahkan tanggung jawab ketersediaan disk dan jaringan ke tangan pengelola klaster Erlang.
Baca cepat dan risikonya#
Operasi di luar transaksi ditolak oleh Mnesia, dan pesan errornya langsung menunjukkan penyebabnya:
1> mnesia:start().
ok
2> mnesia:create_table(siswa, [{attributes, [nama, nilai]}]).
{atomic,ok}
3> mnesia:write({siswa, "Rara", 80}).
** exception exit: {aborted,no_transaction}
in function mnesia:abort/1 (mnesia.erl:728)Pesan no_transaction menegaskan aturan: mutasi tanpa transaksi harus memakai keluarga dirty_* sambil menyadari risikonya. Fungsi dirty_read/1 dan dirty_write/1 melompati transaksi dan jauh lebih murah, tetapi pembacanya bisa melihat keadaan yang belum konsisten, sehingga keluarga ini tepat untuk data yang menoleransi kebenaran sesaat seperti statistik hidup, dan berbahaya untuk data yang menuntut kebenaran penuh seperti pembayaran. Sisi risiko lainnya menyangkut operasi: tabel ram_copies hilang saat VM mati, tabel disc_copies menulis dua kali ke memori dan disk, dan perubahan skema pada klaster yang sedang berjalan adalah operasi yang perlu dipelajari secara khusus.
Kapan tidak memakai Mnesia#
Mnesia bukan basis data umum. Ia tidak memiliki bahasa query standar, tidak memiliki alat administrasi yang setara basis data mainstream, dan penyimpanannya mengikuti struktur node Erlang, sehingga backup dan pemulihannya mengikuti aturan OTP pula. Pembagian yang sehat adalah sebagai berikut: data aplikasi Erlang yang transaksional, tersebar, ukurannya terkendali, dan diakses lewat kunci berada di ranah Mnesia. Selain itu, kandidat yang benar biasanya Mnesia untuk lapisan panas dan basis data eksternal untuk lapisan tetap, dan keduanya hidup berdampingan tanpa masalah.
Ringkasan#
- Mnesia menyimpan data Erlang apa adanya secara transaksional dan terdistribusi, dengan skema per node.
- create_schema/1 menyiapkan disk saat Mnesia belum berjalan, lalu start/0 dan create_table/2 menyalakan penyimpanannya.
- write/1 dan read/1 hanya sah di dalam transaction/1, dan keluarga dirty_* melompati transaksi dengan risiko konsistensi yang disadari.
- Mnesia tepat untuk data sedang yang hidup di klaster Erlang. Data besar dan lintas aplikasi lebih baik di basis data eksternal.
Referensi#
- Mnesia User Guide — Ericsson — Panduan resmi skema, tabel, transaksi, dan distribusi Mnesia.
- mnesia — Ericsson — Referensi resmi fungsi Mnesia beserta semantik transaksinya.
- Learn You Some Erlang for Great Good! — Fred Hebert — Bab Mnesia dengan contoh tabel dan transaksi.