InnoDB bukan sekadar pilihan default — engine ini adalah alasan MySQL bisa dipercaya menampung data aplikasi bank, toko, dan sistem pesanan. Ketiga keunggulannya (transaksi ACID, foreign key, crash recovery) bukan sulap, melainkan hasil kerja tiga komponen arsitektur yang bekerja terkoordinasi: buffer pool di memori, redo log di disk, dan tablespace tempat data tinggal. Memahami ketiganya memberi kita kemampuan membaca angka-angka status InnoDB, menyetel ukuran cache dengan sadar, dan menjawab pertanyaan klasik administrator: “kenapa server makan RAM sebanyak ini?” Chapter ini membedah arsitektur tersebut di atas server latihan yang benar-benar menjalankan InnoDB.

Peta Arsitektur InnoDB #

Diagram berikut merangkum perjalanan data dari koneksi klien hingga file di disk:

Buffer pool adalah area memori tempat InnoDB menampung salinan halaman data dan index (halaman = blok 16 KB). Redo log adalah catatan perubahan yang ditulis sebelum halaman di disk diubah — pola write-ahead logging — sehingga setiap komitmen transaksi hanya perlu menulis catatan kecil ke redo log yang berurutan, jauh lebih murah daripada menulis halaman data yang tersebar acak di disk. Tablespace adalah file fisik tempat halaman-halaman itu akhirnya tinggal. Kolaborasi ketiganya menghasilkan dua hal sekaligus: kecepatan (baca dari RAM, tulis berurutan) dan keamanan (redo log bisa memutar ulang kembali perubahan yang belum sempat sampai ke file data).

Buffer Pool dan Hit Ratio #

Ukuran buffer pool dikendalikan variabel innodb_buffer_pool_size — variabel single terpenting untuk performa server:

sql
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';

Output yang Dihasilkan:

text
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+
1 row in set (0.00 sec)

Server latihan kita mengalokasikan 134217728 byte — tepat 128 MB. Angka ini jauh dari kebutuhan nyata: server produksi umumnya mengalokasikan 50–70% RAM mesin untuk buffer pool, karena semakin besar cache, semakin sedikit bacaan yang harus menembus disk. Efektivitasnya terukur lewat hit ratio — persentase permintaan halaman yang dilayani langsung dari memori:

sql
-- @check
SHOW STATUS LIKE 'Innodb_buffer_pool_read%';

Output yang Dihasilkan:

text
+---------------------------------------+--------+
| Variable_name                         | Value  |
+---------------------------------------+--------+
| Innodb_buffer_pool_read_ahead_rnd     | 0      |
| Innodb_buffer_pool_read_ahead         | 0      |
| Innodb_buffer_pool_read_ahead_evicted | 0      |
| Innodb_buffer_pool_read_requests      | 785925 |
| Innodb_buffer_pool_reads              | 1186   |
+---------------------------------------+--------+
5 rows in set (0.00 sec)

Nilai di server Anda pasti berbeda karena counter ini bersifat kumulatif sejak server menyala — itu sebabnya blok di atas ditandai @check. Dua baris terakhir yang kita perlukan untuk hit ratio: Innodb_buffer_pool_read_requests menghitung total permintaan halaman, sedangkan Innodb_buffer_pool_reads menghitung permintaan yang terpaksa membaca dari disk. Hit ratio dihitung sebagai 1 - reads / requests; pada contoh di atas nilainya 1 - 1186/785925 atau sekitar 99,8%. Hit ratio di bawah 99% pada server produksi sibuk adalah sinyal klasik bahwa buffer pool terlalu kecil untuk ukuran data.

Redo Log dan innodb_redo_log Capacity #

Sejak MySQL 8.0.30, kapasitas redo log diatur oleh satu variabel innodb_redo_log_capacity (byte):

sql
SHOW VARIABLES LIKE 'innodb_redo_log_capacity';

Output yang Dihasilkan:

text
+--------------------------+-----------+
| Variable_name            | Value     |
+--------------------------+-----------+
| innodb_redo_log_capacity | 104857600 |
+--------------------------+-----------+
1 row in set (0.00 sec)

Nilai 104857600 berarti 100 MB — default untuk server kecil. Redo log bekerja seperti buku catatan kasir: setiap perubahan halaman dicatat dulu ke file redo log yang ditulis secara berurutan (sequential), lalu diterapkan ke file data belakangan saat checkpoint. Bila beban tulis tinggi, redo log kecil terisi cepat dan memaksa checkpoint lebih sering — server tersendat oleh penulisan acak ke file data. Menaikkan kapasitas redo log memberi ruang napas lebih panjang; menurunkannya menghemat disk pada beban tulis ringan. Variabel ini bersifat dynamic: bisa di-SET GLOBAL tanpa restart, sesuatu yang jarang bisa dilakukan pada pengaturan fisik.

Tablespace: Satu File .ibd per Tabel #

InnoDB menyimpan datanya dalam unit tablespace. Berkat innodb_file_per_table yang aktif secara default, tiap tabel InnoDB mendapat file .ibd tersendiri di dalam direktori database — berbeda dari model lama yang menumpuk seluruh tabel dalam satu file ibdata1. Kita buktikan lewat metadata InnoDB:

sql
SHOW VARIABLES LIKE 'innodb_file_per_table';
DROP DATABASE IF EXISTS belajar_admin;
CREATE DATABASE belajar_admin;
USE belajar_admin;
CREATE TABLE produk (
  id INT PRIMARY KEY,
  nama VARCHAR(50)
) ENGINE=InnoDB;
SELECT NAME, ROW_FORMAT, SPACE_TYPE
FROM information_schema.INNODB_TABLES
WHERE NAME LIKE 'belajar_admin/%';

Output yang Dihasilkan:

text
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.00 sec)

Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Database changed
Query OK, 0 rows affected (0.00 sec)

+----------------------+------------+------------+
| NAME                 | ROW_FORMAT | SPACE_TYPE |
+----------------------+------------+------------+
| belajar_admin/produk | Dynamic    | Single     |
+----------------------+------------+------------+
1 row in set (0.00 sec)

Tabel INNODB_TABLES milik information_schema memperlihatkan registry internal InnoDB: tabel kita terdaftar sebagai belajar_admin/produk (pemisahnya garis miring), dengan SPACE_TYPE Single yang menegaskan tablespace terpisah milik satu tabel. Di disk, file-nya berada di belajar_admin/produk.ibd dalam data directory. File per tabel mempermudah banyak hal praktis: tabel bisa di-DROP lalu membebaskan disknya seketika, ukuran file terlihat langsung dengan ls, dan tabel besar bisa ditempatkan di disk terpisah dengan klausa DATA DIRECTORY. Sisa kebutuhan sistem — katalog internal, undo log, dan perubahan metadata — tetap ditampung tablespace bersama ibdata1:

sql
SHOW VARIABLES LIKE 'innodb_data_file_path';

Output yang Dihasilkan:

text
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+-----------------------+------------------------+
1 row in set (0.00 sec)

Nilai ibdata1:12M:autoextend berarti file sistem itu mulai 12 MB dan tumbuh otomatis bila diperlukan.

Row Format Dynamic #

Cara InnoDB menyusun kolom-kolom di dalam halaman diatur row format, dan default-nya sejak lama adalah Dynamic:

sql
SHOW VARIABLES LIKE 'innodb_default_row_format';

Output yang Dihasilkan:

text
+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| innodb_default_row_format | dynamic |
+---------------------------+---------+
1 row in set (0.00 sec)

Format Dynamic menyimpan nilai-nilai pendek sepenuhnya di halaman index, tetapi memindahkan nilai panjang (BLOB besar, string raksasa) ke halaman overflow terpisah dan meninggalkan penunjuk 20-byte di tempatnya. Efeknya: baris tetap ramping sehingga satu halaman 16 KB memuat banyak baris dan index tetap padat. SHOW CREATE TABLE tidak menampilkan ROW_FORMAT pada tabel kita justru karena Dynamic adalah nilai default — MySQL menghilangkan opsi yang sama dengan nilai bawaannya.

Crash Recovery: Keunggulan yang Tak Terlihat #

Keunggulan paling berharga InnoDB justru bekerja saat keadaan terburuk: server mati mendadak karena listrik atau proses terbunuh. Saat menyala kembali, InnoDB menjalankan pemulihan otomatis — membaca redo log dan memutar ulang setiap perubahan dari transaksi yang sudah dikomit tetapi belum sempat sampai ke file data, lalu membatalkan jejak transaksi yang belum selesai lewat undo log. Hasilnya server kembali konsisten sampai koma terakhir tanpa campur tangan kita. Bandingkan dengan tabel MyISAM pada keadaan yang sama: file data bisa berhenti di tengah tulisan dan tabelnya rusak sampai di-REPAIR. Asuransi ini juga yang membuat pernyataan COMMIT InnoDB punya arti sungguhan — janji bahwa data bertahan melewati crash.

Referensi #

Mesin penyimpanan sudah kita pahami sampai ke arsitekturnya. Berikutnya kita melihat pintu masuk ke server itu sendiri: bagaimana koneksi-koneksi klien diterima, dibatasi, dan diakhiri — topik connection management.