Ketika server tiba-tiba melambat, pertanyaan pertama administrator bukan “kenapa?” melainkan “siapa yang sedang melakukan apa?”. Jawabannya ada di process list — daftar seluruh koneksi yang sedang hidup beserta query yang sedang dijalaninya. Dari jendela ini kita bisa melihat query yang macet belasan menit, koneksi yang menganggur sejak pagi, hingga transaksi yang mengunci tabel dan membuat antrean. Chapter ini membaca process list dari dua pintu (SHOW PROCESSLIST dan information_schema.PROCESSLIST), memahami arti tiap kolomnya, lalu mempraktikkan KILL untuk mengakhiri koneksi dan KILL QUERY untuk membatalkan query yang berlarat-larut.
Jendela ke Semua Koneksi: SHOW PROCESSLIST #
Kita siapkan database latihan supaya kolom db di process list terisi, lalu intip daftar koneksinya:
DROP DATABASE IF EXISTS belajar_admin;
CREATE DATABASE belajar_admin;
USE belajar_admin;
CREATE TABLE pelanggan (id INT PRIMARY KEY, nama VARCHAR(50));Output yang Dihasilkan:
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)-- @check
SHOW PROCESSLIST;Output yang Dihasilkan:
+----+-----------------+-----------------+---------------+---------+-------+------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-----------------+-----------------+---------------+---------+-------+------------------------+------------------+
| 5 | event_scheduler | localhost | NULL | Daemon | 42 | Waiting on empty queue | NULL |
| 12 | root | localhost:52984 | belajar_admin | Query | 0 | init | SHOW PROCESSLIST |
+----+-----------------+-----------------+---------------+---------+-------+------------------------+------------------+
2 rows in set, 1 warning (0.00 sec)Baris Id, angka Time, dan port pada kolom Host bersifat berubah-ubah antar server dan antar waktu — di server Anda pasti berbeda — sehingga blok di atas ditandai @check. Dua baris yang tampil bercerita banyak: baris pertama adalah thread event_scheduler internal yang berjalan sejak server menyala (Daemon, menunggu antrean event), dan baris kedua adalah koneksi kita sendiri — terlihat dari Info yang berisi statement SHOW PROCESSLIST yang bahkan belum selesai dieksekusi saat daftar ini diambil. Kolom-kolomnya bekerja sebagai berikut:
| Kolom | Arti |
|---|---|
Id | nomor koneksi — nomor inilah yang dipakai KILL |
User dan Host | akun dan asal koneksi, berguna melacak klien nakal |
db | database aktif koneksi itu, NULL bila belum memilih |
Command | jenis pekerjaan yang sedang dilakukan thread |
Time | detik sejak thread berada pada Command/State saat ini |
State | tahap internal eksekusi (mis. executing, Sending data) |
Info | teks statement yang sedang berjalan |
Bentuk SHOW FULL PROCESSLIST menampilkan kolom Info utuh; tanpa FULL, teks statement dipotong pada 100 karakter pertama. Saat insiden, SHOW FULL PROCESSLIST adalah bentuk yang kita inginkan — panjang query yang bermasalah sering justru ada di klausa-klausa setelah karakter ke-100.
Membaca Command dan State #
Kolom Command membagi thread ke dalam beberapa jenis pekerjaan yang maknanya perlu hafal:
| Nilai Command | Arti |
|---|---|
Query | sedang mengeksekusi sebuah statement |
Sleep | koneksi terbuka tapi idle — menunggu perintah berikutnya |
Killed | statement sedang dibatalkan, biasanya masih membersihkan |
Daemon | thread internal server, bukan klien (mis. event scheduler) |
Connect | proses handshake koneksi baru |
Quit | koneksi sedang menutup diri |
Binlog Dump | thread replikasi yang mengalirkan binlog ke replica |
Gabungan Command dan Time adalah alat diagnosis paling cepat: baris Query dengan Time 250 berarti ada statement yang sudah berjalan 4 menit lebih — kandidit utama penyebab kelambatan; baris Sleep dengan Time 8000 di banyak jumlah adalah koneksi terlupakan yang memakan slot max_connections. Kolom State melengkapi dengan tahap internalnya — Sending data lama biasanya berarti scan besar tanpa index, sementara Waiting for table metadata lock menandakan DDL yang mengunci struktur tabel.
Process List lewat information_schema #
Selain perintah SHOW, process list juga tersedia sebagai tabel information_schema.PROCESSLIST yang bisa kita saring dengan WHERE layaknya query biasa — hal yang tidak bisa dilakukan SHOW PROCESSLIST:
USE belajar_admin;
SELECT USER, COMMAND, DB, INFO
FROM information_schema.PROCESSLIST
WHERE ID = CONNECTION_ID();
SHOW WARNINGS;Output yang Dihasilkan:
Database changed
+------+---------+---------------+-----------------------------------------------------------------------------------------------+
| USER | COMMAND | DB | INFO |
+------+---------+---------------+-----------------------------------------------------------------------------------------------+
| root | Query | belajar_admin | SELECT USER, COMMAND, DB, INFO
FROM information_schema.PROCESSLIST
WHERE ID = CONNECTION_ID() |
+------+---------+---------------+-----------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 1287 | 'INFORMATION_SCHEMA.PROCESSLIST' is deprecated and will be removed in a future release. Please use performance_schema.processlist instead |
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)Filter WHERE ID = CONNECTION_ID() memangkas daftar ke koneksi kita sendiri, dan hasilnya memperlihatkan dirinya sendiri sedang menjalankan statement ini — kolom INFO berisi teks query yang belum selesai. Nama kolom di sini huruf besar (ID, USER, DB) karena information_schema menyimpan namanya demikian. Warning 1287 yang menyertainya penting dicatat: MySQL menandai tabel ini deprecated dan menganjurkan performance_schema.processlist sebagai penggantinya. Di server latihan kita performance schema sedang mati sehingga tabel penggantinya kosong, namun di server produksi modern dengan performance schema aktif, tabel performance_schema.processlist memang jadi sumber yang lebih kaya — kolomnya bisa digabung dengan tabel metrik lain seperti events_statements_current tanpa perlu perintah SHOW terpisah.
Mengakhiri Koneksi dengan KILL #
Perintah KILL <Id> memutus koneksi beserta pekerjaannya, sedangkan KILL QUERY <Id> hanya membatalkan statement yang sedang berjalan dan membiarkan koneksinya hidup. Nomor yang dipakai adalah Id dari process list. Kita uji yang kedua lebih dulu terhadap nomor koneksi yang tidak ada:
-- @error
KILL QUERY 999999;Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
ERROR 1094 (HY000): Unknown thread id: 999999
ByeError 1094 adalah respons server terhadap nomor koneksi yang tidak dikenal — memastikan perintah kita menunjuk objek yang benar-benar ada. Sekarang demo yang sesungguhnya: mematikan koneksi kita sendiri. Fungsi CONNECTION_ID() mengembalikan nomor koneksi saat ini, jadi kita bisa menjadikannya argumen KILL tanpa tahu nomornya terlebih dahulu:
-- @error
KILL CONNECTION_ID();Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
ERROR 1317 (70100): Query execution was interrupted
ByePerintah ini benar-benar membunuh sesi tempat ia berjalan: klien menerima ERROR 1317 bahwa eksekusinya diinterupsi, lalu menutup dirinya (baris Bye). Skenario dua terminal berikut memperlihatkan pemakaian yang lebih lazim — mengakhiri koneksi orang lain dari sesi admin:
-- @notest
-- Terminal 1: sesi klien yang dibiarkan menganggur
SELECT SLEEP(30);-- @notest
-- Terminal 2: sesi admin yang mengawasi dan bertindak
SHOW FULL PROCESSLIST;
KILL 12;Di terminal 1, sesi klien menjalankan SELECT SLEEP(30) yang selama 30 detik tampil di process list milik terminal 2 sebagai baris Query dengan Time yang terus bertambah. Begitu admin menjalankan KILL 12 (nomor Id baris tersebut), statement SLEEP di terminal 1 langsung terputus dengan error yang sama seperti demo kita barusan — dan jika klien segera menjalankan statement lain, koneksinya sendiri sudah tidak ada. Di server yang benar-benar sibuk, inilah gerakan cepat membebaskan server dari query yang mengunci atau berjalan berjam-jam.
Query Stuck dan Koneksi Idle #
Dua pola masalah paling sering terbaca langsung dari process list. Pola pertama, query stuck: satu atau beberapa baris Query dengan Time yang terus naik tiap kali kita menjalankan SHOW PROCESSLIST — perhatikan kolom State untuk menebak tahap yang macet, cek Info untuk melihat query-nya, lalu putuskan KILL QUERY atau perbaiki indexnya bila pola ini berulang. Pola kedua, idle connections: deretan baris Sleep yang jumlahnya besar dan Time-nya panjang — ini urusan wait_timeout dan connection pooling dari chapter sebelumnya, bukan KILL massal. Kombinasi keduanya yang paling berbahaya: baris Sleep lama yang diam-diam memegang transaksi terbuka dan kunci baris — information_schema.INNODB_TRX (topik tingkat lanjut) bisa memastikan transaksi mana yang masih hidup di balik baris Sleep tersebut.
Membersihkan Latihan #
Database latihan chapter ini kita rapikan seperti biasa supaya process list server kembali bersih:
DROP DATABASE belajar_admin;Output yang Dihasilkan:
Query OK, 1 row affected (0.00 sec)Referensi #
- SHOW PROCESSLIST Statement — MySQL 8.4 Reference Manual
- Connection Management — MySQL 8.4 Reference Manual
- The INFORMATION_SCHEMA INFORMATION_SCHEMA Tables — MySQL 8.4 Reference Manual
Kini kita bisa melihat siapa yang bekerja di server. Pertanyaan level berikutnya adalah seberapa banyak dan seberapa lama — angka-angka agregat tentang seluruh riwayat server yang tersaji rapi di SHOW STATUS, topik chapter berikutnya.