Angka SHOW STATUS dan process list hanya menggambarkan kondisi saat ini. Begitu terjadi insiden — server gagal menyala, query misterius mengubah data, atau aplikasi mendadak melambat — kita membutuhkan rekam jejak kejadian, dan itulah pekerjaan log. MySQL memelihara empat log utama dengan karakter yang berbeda: error log untuk kesehatan server, general query log untuk semua statement yang lewat, slow query log untuk query yang kelewat lambat, dan binary log untuk perubahan data yang dapat diputar ulang. Chapter ini membaca jenis-jenis log tersebut, membuktikan cara mengalihkan general log ke tabel agar bisa di-SELECT, lalu menutup dengan kebiasaan merawat ukuran log agar tidak membanjiri disk.
Peta Empat Jenis Log #
Empat log tersebut berbeda isi, keadaan default, dan cara membacanya:
| Log | Isi | Default | Tujuan utama |
|---|---|---|---|
| Error log | pesan startup, warning, error, shutdown | aktif | diagnosis kesehatan server |
| General query log | seluruh statement dari semua klien | mati | melacak aktivitas |
| Slow query log | query yang melewati ambang waktu | mati | investigasi performa |
| Binary log | event perubahan data | mati di server uji | replikasi dan point-in-time recovery |
Perlu dicermati bahwa hanya error log yang menyala begitu server diinstal. Tiga log lainnya sengaja mati karena menulis semuanya ke disk itu mahal — bayangkan general query log merekam setiap statement dari ribuan koneksi per detik. Pola kerja sehari-hari administrator adalah mengaktifkan log yang dibutuhkan untuk jendela investigasi tertentu, lalu mematikannya kembali.
Error Log: Log yang Selalu Ada #
Lokasi error log tersimpan di variabel log_error:
-- @check
SHOW VARIABLES LIKE 'log_error';Output yang Dihasilkan:
+---------------+--------------------------+
| Variable_name | Value |
+---------------+--------------------------+
| log_error | /var/log/mysql/error.log |
+---------------+--------------------------+Nilai persisnya berbeda antar instalasi — paket Debian/Ubuntu lazimnya memakai /var/log/mysql/error.log, distribusi berbasis RPM memakai /var/log/mysqld.log, dan server yang dijalankan manual tanpa opsi --log-error mengalirkan pesannya ke standard error. Isinya berformat baris berstempel waktu dengan tingkat keparahan di dalam kurung siku:
2026-10-14T07:31:02.114238Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4) starting as process 1841
2026-10-14T07:31:02.921155Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS.
2026-10-14T07:31:03.118367Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2026-10-14T07:31:03.301188Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections.Kutipan di atas adalah tampilan error log yang sehat: baris [System] mencatat urutan startup hingga server siap menerima koneksi. Saat server bermasalah, baris [ERROR] adalah yang kita cari — kegagalan membuka port, korupsi tabel, atau opsi konfigurasi yang salah semuanya tercatat di sini. Kebiasaan pertama saat menghadapi server yang “tidak mau menyala” adalah membaca file ini dari baris paling akhir ke belakang.
General Query Log: Merekam Semua Statement #
General query log merekam semua statement dari semua koneksi — SELECT, INSERT, DDL, bahkan koneksi yang masuk dan keluar. Statusnya mati secara default, dan variabel log_output menentukan tujuan penulisannya:
SHOW VARIABLES LIKE 'general_log';
SHOW VARIABLES LIKE 'log_output';Output yang Dihasilkan:
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| general_log | OFF |
+---------------+-------+
1 row in set (0.00 sec)
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output | FILE |
+---------------+-------+
1 row in set (0.00 sec)Nilai log_output FILE berarti log ditulis ke file teks. Pilihan lainnya adalah TABLE, yang mengalirkan log ke tabel mysql.general_log — dan begitu log menjadi tabel, kita bisa menyaringnya dengan WHERE layaknya data biasa. Kita aktifkan keduanya dan langsung menghasilkan aktivitas:
SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = ON;
SELECT 1 + 1 AS latihan_aritmetika;Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
+--------------------+
| latihan_aritmetika |
+--------------------+
| 2 |
+--------------------+
1 row in set (0.00 sec)Baris Query OK pada statement kedua menandakan perekaman sudah hidup. Sekarang kita baca isi mysql.general_log — sesi baru ini sendiri langsung terekam, termasuk statement banner pembuka dari klien. Satu keunikan perlu kita tangani: kolom argument bertipe mediumblob (biner), sehingga klien menampilkannya sebagai deretan heksadesimal; fungsi CONVERT(argument USING utf8mb4) mengubahnya kembali menjadi teks:
-- @check
SELECT event_time, user_host, command_type,
CONVERT(argument USING utf8mb4) AS teks_statement
FROM mysql.general_log
WHERE command_type = 'Query'
ORDER BY event_time;Output yang Dihasilkan:
+----------------------------+------------------------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| event_time | user_host | command_type | teks_statement |
+----------------------------+------------------------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 2026-10-14 15:36:07.454593 | root[root] @ localhost [127.0.0.1] | Query | SELECT 1 + 1 AS latihan_aritmetika |
| 2026-10-14 15:36:07.737893 | root[root] @ localhost [127.0.0.1] | Query | select @@version_comment limit 1 |
| 2026-10-14 15:36:08.427741 | root[root] @ localhost [127.0.0.1] | Query | SELECT event_time, user_host, command_type,
CONVERT(argument USING utf8mb4) AS teks_statement
FROM mysql.general_log
WHERE command_type = 'Query'
ORDER BY event_time |
+----------------------------+------------------------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)Tabel hasilnya menampilkan kolom yang cukup menjelaskan dirinya sendiri: event_time adalah waktu kejadian dengan presisi mikrodetik, user_host akun dan asal koneksi, command_type jenis statement, dan teks_statement isi statementnya utuh. Statement SELECT 1 + 1 yang kita jalankan sebelumnya terlihat, disusul statement banner klien dan statement pembaca log itu sendiri — bukti bahwa perekaman berlaku seketika dan menyeluruh. Blok ini ditandai @check karena event_time dan identitas koneksi pasti berbeda setiap kali dijalankan; struktur tabel dan pola barisnya itulah yang stabil.
Setelah selesai menyelidiki, tiga pengaturan perlu dikembalikan agar server kembali ke kondisi semula:
SET GLOBAL general_log = OFF;
SET GLOBAL log_output = 'FILE';
TRUNCATE TABLE mysql.general_log;Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)Ketiga statement ini adalah disiplin wajib: general log dimatikan, tujuan log dikembalikan ke FILE, dan tabel log dikosongkan dengan TRUNCATE supaya tidak menyimpan jejak sesi latihan. Melewatkan langkah ini membuat seluruh statement berikutnya di server uji terus menambah baris ke tabel CSV yang tidak pernah mengecil sendiri.
Binary Log: Rekaman Perubahan untuk Pemulihan #
Log terakhir berbeda dari tiga sebelumnya: binary log (binlog) tidak merekam teks statement semata, melainkan event perubahan data dalam format biner — siap diputar ulang untuk replikasi atau memulihkan data sampai titik waktu tertentu (point-in-time recovery). Keadaannya di server uji kita:
SHOW VARIABLES LIKE 'log_bin';Output yang Dihasilkan:
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | OFF |
+---------------+-------+
1 row in set (0.00 sec)Nilai OFF di sini karena server latihan sengaja dijalankan tanpa binary logging. Instalasi produksi MySQL 8.4 pada umumnya justru menyimpannya aktif secara default, karena binlog menjadi fondasi dua fitur penting sekaligus: replica membacanya untuk menyalin data, dan prosedur pemulihan memutarnya ulang di atas backup terakhir. Karena sifatnya yang menuntut opsi startup dan rotasi terkelola, pembahasan mendalam binlog — membaca isinya dengan mysqlbinlog, mengatur masa simpan, dan memakainya dalam recovery — kita serahkan ke section Backup dan Recovery.
Merawat Ukuran Log #
Semua log bertumbuh, dan tiga kebiasaan menjaga agar pertumbuhannya terkendali. Pertama, rotasi: FLUSH LOGS (atau mysqladmin flush-logs) menutup dan membuka kembali file log sehingga file lama bisa diarsipkan atau dihapus oleh alat rotasi seperti logrotate di Linux. Kedua, kadaluarsa binlog: variabel binlog_expire_logs_seconds mengatur otomatis penghapusan file binlog tua setelah replikasi selesai memakainya. Ketiga, kebersihan tabel log: mysql.general_log dan mysql.slow_log hanya pernah mengecil melalui TRUNCATE saat lognya sedang mati. Kombinasi ketiganya menjaga direktori log tetap seukuran kebutuhan, bukan seukuran usia server.
Referensi #
- Server Logs — MySQL 8.4 Reference Manual
- The Error Log — MySQL 8.4 Reference Manual
- Selecting General Query Log and Slow Query Log Output Destinations — MySQL 8.4 Reference Manual
- The Binary Log — MySQL 8.4 Reference Manual
General query log merekam semuanya tanpa pandang bulu — berguna untuk melacak aktivitas, tapi miskin sinyal saat mencari penyebab kelambatan. Untuk itu MySQL menyediakan slow query log yang hanya menangkap query melewati ambang waktu tertentu; chapter berikutnya mengaktifkan, membaca, dan memanfaatkan log tersebut sebagai titik awal optimasi.