Pita hitam pesawat mencatat segala hal yang terjadi penerbangan; binary log menjalankan peran yang sama untuk database. Ia adalah deretan file berisi setiap perubahan data yang pernah diterapkan server — bukan hanya hasil akhirnya, tetapi perintah perubahannya, berurutan sesuai waktu terjadinya. Dari catatan inilah replikasi menggandakan server, dan point-in-time recovery mengejar waktu seperti yang kita bahas di chapter sebelumnya. Sekaligus, binary log juga menjadi salah satu istilah yang paling sering disalahpahami — banyak yang mencampurnya dengan redo log InnoDB padahal keduanya berbeda peran sepenuhnya. Chapter ini membedahnya tuntas: isinya, formatnya, cara membacanya, dan garis pemisahnya dari redo log.

Apa yang Dicatat Binary Log #

Rumusnya ringkas: semua yang mengubah data atau struktur, dan hanya yang berhasil. Statement INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE, DROP — semuanya menulis event ke binary log pada saat transaksinya commit. Sebaliknya, SELECT tidak pernah dicatat karena tidak mengubah apa pun, dan transaksi yang di-rollback juga tidak meninggalkan jejak. Setiap event mendapat penanda posisi — alamat byte dalam file binlog, dikenal lewat end_log_pos — yang menjadi dasar penunjukan titik henti replay pada PITR.

Realita Server Latihan Kita #

Kita mulai dengan bertanya langsung kepada server, apakah binary log menyala:

sql
SHOW VARIABLES LIKE 'log_bin';

Output yang Dihasilkan:

text
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

Jawabannya OFF — sesuai catatan di atas. Konsekuensinya langsung terasa pada perintah-perintah administratif binlog. SHOW BINARY LOGS yang seharusnya menampilkan daftar file binlog beserta ukurannya menolak bekerja:

sql
-- @error
SHOW BINARY LOGS;

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

ERROR 1381 (HY000): You are not using binary logging
Bye

Sedangkan SHOW BINARY LOG STATUS — perintah kunci untuk mengetahui file binlog aktif dan posisi ujungnya — berhasil dijalankan tetapi pulang tanpa membawa apa pun:

sql
SHOW BINARY LOG STATUS;

Output yang Dihasilkan:

text
Empty set (0.00 sec)

Empty set dari perintah kedua adalah potret jujur server tanpa binlog: tidak ada file, tidak ada posisi, tidak ada apa pun untuk dilaporkan. Di server produksi dengan binlog aktif, keluaran SHOW BINARY LOG STATUS justru menjadi angka paling berharga saat insiden: nama file binlog yang sedang ditulis dan posisi end_log_pos terakhir — bahan mentah menentukan titik henti replay PITR. (Satu catatan sejarah: di MySQL 8.2 ke bawah perintah ini bernama SHOW MASTER STATUS; sintaks lama sudah dihapus di 8.4, j tutorial tua yang masih memakainya perlu dibaca dengan sadar.)

Format Event: ROW, STATEMENT, MIXED #

Cara binlog “memotret” satu perubahan ditentukan variabel binlog_format. Pilihan formatnya tiga, dan pilihan kita memengaruhi ukuran log, keamanan replikasi, dan ketepatan replay:

AspekROWSTATEMENTMIXED
Yang dicatatPerubahan per baris (bayangan sebelum & sesudah)Statement SQL aslinyaStatement, beralih ke ROW bila berisiko
Ukuran eventBesar (UPDATE 1 juta baris = 1 juta event)Kecil (satu statement)Bervariasi
Determinisme replayPaling aman — hasil pasti samaRentan fungsi waktu/acak: NOW(), UUID(), RAND()Aman (bagian berisiko pakai ROW)
Keterbacaan manusiaRendah — perlu mysqlbinlog --base64-outputTinggi — SQL asli terbacaCampuran
Khasat replikasiServer replika persis samaReplika bisa melebar dari sumberKompromi

Default MySQL 8.4 sudah menetapkan format paling aman, dan server latihan kita mengikutinya meski binlognya mati:

sql
SHOW VARIABLES LIKE 'binlog_format';

Output yang Dihasilkan:

text
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

Nilai ROW menegaskan arah industri: determinisme replay dihargai lebih tinggi daripada ukuran log. Sebuah UPDATE stok = stok - 1 WHERE kategori = 'teh' dalam format ROW dicatat sebagai deretan pasangan baris lama-baru — replika dan replay PITR menerapkan hasil akhir yang sama tanpa perlu menghitung ulang kondisi WHERE; dalam format STATEMENT, perintah itu dijalankan ulang dari nol dan bisa mengenai himpunan baris yang berbeda bila data pembandingnya sudah melebar.

Retensi: Berapa Lama Binlog Disimpan #

File binlog tumbuh terus selama server menulis, sehingga MySQL membersihkannya sendiri lewat variabel binlog_expire_logs_seconds:

sql
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';

Output yang Dihasilkan:

text
+----------------------------+---------+
| Variable_name              | Value   |
+----------------------------+---------+
| binlog_expire_logs_seconds | 2592000 |
+----------------------------+---------+
1 row in set (0.00 sec)

Nilai bawaan 2592000 detik adalah tepat 30 hari — binlog yang lebih tua dari itu dibersihkan otomatis saat log dirotasi. Angka ini bukan sekadar kebersihan disk: ia adalah umur maksimum kemampuan PITR Anda. Rantai replay butuh binlog yang utuh sejak base backup terakhir; binlog yang terhapus lebih cepat daripada siklus backup memutus rantai itu dan diam-diam mengembalikan RPO Anda ke jadwal backup.

Membaca binlog dengan mysqlbinlog #

File binlog adalah berkas biner — dibuka dengan editor teks hanya menghasilkan kekacauan. Pembaca resminya adalah program mysqlbinlog, yang menerjemahkan event menjadi teks yang bisa dibaca manusia maupun diputar ulang ke server. Sebuah event dalam keluaran mysqlbinlog tampak seperti ini (ilustrasi):

text
#260314 14:36:58 server id 1  end_log_pos 745 Query thread_id=12 exec_time=0
use belajar_backup;
INSERT INTO produk (nama, harga, stok) VALUES ('Kopi Luwak', 120000, 5);

Tiga informasi pada potongan di atas adalah kunci pembacaan binlog. Sebelum setiap header seperti ini, mysqlbinlog juga mencetak baris alamat awal event (berbunyi # at 678) yang bersama end_log_pos 745 membentuk rentang posisi — dua angka inilah yang dipakai sebagai --start-position dan --stop-position saat replay. Stempel waktu #260314 14:36:58 (tanggal 26-03-14, pukul 14:36:58) menjadi dasar mode --stop-datetime. Dalam format ROW, bagian isi event berubah menjadi blok terenkode BINLOG'...' yang memuat bayangan baris sebelum-sesudah — tetap bisa diputar ulang, hanya tidak lagi terbaca mata. Perintah sehari-harinya ringkas:

bash
-- @notest
mysqlbinlog /var/lib/mysql/binlog.000001 | less
mysqlbinlog --start-position=678 --stop-position=745 /var/lib/mysql/binlog.000001 | mysql -h 127.0.0.1 -P 3306 -u root

Baris pertama membaca log untuk diteliti; baris kedua memutar ulang rentang event tertentu ke server. Kedua contoh memakai path ilustratif — di server Anda, lokasi file binlog mengikuti datadir dan prefiksnya diatur opsi log_bin_basename.

Binlog Bukan Redo Log InnoDB #

Inilah pembahasan penutup yang paling penting, karena dua istilah ini paling sering tertukar — keduanya sama-sama “log yang mencatat perubahan”, tetapi tujuannya bertolak belakang.

Redo log InnoDB adalah log internal milik storage engine InnoDB untuk satu tujuan: crash recovery. Saat transaksi commit, perubahan ditulis ke redo log di disk lebih dulu (mekanisme write-ahead logging) sebelum halaman data di buffer pool sempat disiram ke file data. Bila server tiba-tiba mati, saat menyala kembali InnoDB membaca redo log dan “menuntaskan” penulisan halaman yang belum selesai — dunianya kembali konsisten tanpa satu transaksi commit pun hilang. Redo log berukuran kecil, berputar terus seperti arena melingkar, tidak pernah dibaca manusia, dan tidak pernah dipakai untuk memutar ulang waktu ke titik arbitrer.

Binary log adalah log di lapisan server, di atas semua storage engine, untuk dua tujuan: replikasi dan PITR. Isinya adalah sejarah perubahan yang bisa diputar ulang di server lain atau di waktu lain — termasuk membangun ulang ke titik sebelum insiden. Saat normal jalan, keduanya dikoordinasikan lewat two-phase commit internal: transaksi menandai dirinya “siap” di sisi InnoDB, menulis event ke binlog, lalu menyelesaikan commit di kedua sisi — sinkron sedemikian rupa sehingga server yang mati di titik mana pun tetap bisa menyimpulkan secara konsisten transaksi mana yang sah.

AspekBinary logRedo log InnoDB
LapisanServer — semua storage engineInternal InnoDB saja
Tujuan utamaReplikasi + PITRCrash recovery setelah mati mendadak
IsiSejarah perubahan yang bisa diputar ulangPenulisan halaman yang belum selesai
Ukuran & umurTumbuh, dirotasi, dipurge lewat retensiKecil dan tetap, terus menimpa dirinya
Dibaca manusiaYa, lewat mysqlbinlogTidak pernah
Bisa memutar ke titik waktu?Ya — itu fungsinyaTidak — hanya meneruskan ke titik terakhir yang sah

Referensi #

Kotak hitam kini terbaca: kita tahu apa yang dicatatnya, tiga cara pencatatannya, umur simpannya, cara membacanya, dan garis batasnya dari redo log. Satu keping terakhir membuat seluruh pengetahuan ini bekerja tanpa bergantung pada ingatan manusia: jadwal. Chapter berikutnya merakit semuanya menjadi strategi terjadwal — full backup mingguan plus binlog harian, cron sebagai penabuh beduknya, rotasi dan retensi sebagai disiplinnya, serta skrip monitoring yang memastikan backup benar-benar berjalan setiap malam.