Bali, Indonesia
Insights

Kenapa Disk Tetap Penuh Padahal File Log Sudah Dihapus

October 15, 2026
0:00
Kamu mungkin pernah mendapati partisi server tiba-tiba menyentuh 99 atau 100 persen, lalu menemukan satu file log berukuran puluhan gigabyte yang terus membengkak. Reaksi pertama yang paling umum dilakukan adalah langsung mengeksekusi rm pada file tersebut agar kapasitas kembali lega. Namun setelah file itu hilang dari daftar folder, perintah pengecekan disk tetap melaporkan bahwa partisi masih penuh, seolah-olah data raksasa tadi tidak pernah dihapus. Situasi ini sangat sering membingungkan pengelola server pemula maupun staf teknis yang baru bertugas di meja bantuan. Masalah ini bukan disebabkan oleh bug pada sistem operasi, partisi yang korup, atau kegagalan perangkat keras penyimpanan. Sistem Linux bekerja dengan aturan ketat seputar siklus hidup file, di mana nama file di dalam folder dan alokasi blok data fisik di media penyimpanan adalah dua entitas yang berbeda.
Langkah awal yang biasanya membuktikan adanya anomali ini adalah membandingkan pembacaan dua perintah standar Linux: df (disk filesystem) dan du (disk usage). Ketika kamu menjalankan df -h, utilitas ini meminta informasi langsung dari superblock sistem file (lewat panggilan sistem seperti statvfs). Superblock menyimpan metadata global tentang berapa banyak total blok data yang tersedia, berapa yang sedang terpakai, dan berapa yang tersisa. Jika suatu proses masih mengunci ruang penyimpanan, superblock akan tetap mencatat blok-blok tersebut sebagai terpakai. Hasilnya, df tetap menampilkan status partisi penuh. Sebaliknya, ketika kamu mengeksekusi du -sh /var/log atau direktori lainnya, utilitas du bekerja dengan cara menelusuri hierarki direktori (tree traversal) satu per satu. du membaca setiap entri direktori (dentry), menanyakan ukuran inode yang terhubung, lalu menjumlahkannya. Karena file log sudah dihapus dari daftar direktori menggunakan perintah rm, du tidak dapat lagi menemukan namanya. Akibatnya, du melaporkan bahwa penggunaan ruang simpan sudah turun drastis, sementara df bersikeras partisi tersebut masih sesak. Jurang pemisah antara keluaran df dan du adalah tanda paling pasti bahwa ada blok data yang tertahan di memori sistem file meskipun namanya sudah tidak ada di sistem direktori.
Untuk memahami alasan di balik perilaku ini, kita perlu melihat bagaimana sistem file POSIX (seperti ext4 atau XFS) mengelola file. Di Linux, data fisik disimpan di dalam kumpulan blok data yang dipetakan oleh struktur bernama inode. Nama file yang kamu lihat di folder hanyalah sebuah hard link—sebuah pointer atau penunjuk dari teks nama file ke nomor inode tertentu. Perintah rm sebenarnya bukan singkatan dari remove data, melainkan menjalankan system call unlink(). Saat kamu menjalankan perintah tersebut, kernel Linux hanya mencabut keterikatan antara nama file dan inode-nya, lalu mengurangi nilai penghitung tautan (link count atau i_nlink) pada inode tersebut sebanyak satu angka. Blok-blok data di media simpan hanya akan dikembalikan ke daftar blok bebas (free block list) apabila dua kondisi terpenuhi secara bersamaan. Pertama, nilai link count harus bernilai nol (tidak ada nama file atau hard link lain yang mengarah ke inode tersebut). Kedua, penghitung referensi terbuka (open file descriptor reference count) juga harus bernilai nol. Jika sebuah aplikasi—misalnya Nginx, Apache, MySQL, atau skrip aplikasi latar belakang—sedang membuka file tersebut saat kamu mengeksekusi rm, aplikasi itu memegang sebuah file descriptor yang valid. Kernel Linux menghormati proses yang sedang berjalan ini. Meskipun nama filenya sudah lenyap dari direktori, kernel tetap mempertahankan blok-blok data fisik di penyimpanan agar aplikasi tidak mengalami crash saat membaca atau menulis ke file descriptor tersebut. Bahkan, aplikasi tersebut bisa terus menulis data log baru ke blok data yang tidak terlihat itu, membuat kapasitas penyimpanan semakin menyusut.
Untuk membebaskan kapasitas penyimpanan, kamu harus menemukan proses mana yang masih mengunci file yang sudah dihapus tersebut. Utilitas yang paling tepat untuk tugas ini adalah lsof (list open files). Kamu bisa memfilter pencarian pada file-file yang link count-nya sudah nol tetapi masih dipegang oleh proses aktif. Jalankan perintah diagnostik berikut menggunakan akses root atau sudo:
BASH
lsof +L1
Opsi +L1 menginstruksikan lsof untuk mencari semua file terbuka yang memiliki jumlah link kurang dari satu. Jika sistem kamu belum mendukung opsi ini secara langsung, perintah alternatif yang sangat umum digunakan adalah memfilter kata kunci deleted:
BASH
lsof / | grep -i '(deleted)'
Pada keluaran perintah tersebut, kamu akan melihat kolom nama proses (COMMAND), identitas proses (PID), nomor file descriptor (FD), ukuran file (SIZE), serta nama file aslinya yang ditandai dengan label (deleted). Dari informasi ini, kamu bisa langsung mengetahui aplikasi apa yang bertanggung jawab menahan ruang simpan tersebut, apakah itu web server, database, atau layanan antrean aplikasi.
Banyak orang memilih jalan pintas dengan me-reboot seluruh server begitu menghadapi masalah ini. Saat server dimatikan, semua proses dihentikan, file descriptor tertutup, dan kernel akhirnya membebaskan blok-blok penyimpanan yang tertahan. Namun, me-reboot mesin produksi yang melayani trafik aktif jelas merupakan langkah yang tidak perlu dan memicu downtime layanan. Ada dua cara yang jauh lebih elegan dan aman untuk menyelesaikan masalah ini secara langsung.
Sebagian besar aplikasi server dirancang untuk mengenali kebutuhan rotasi log tanpa harus dimatikan seutuhnya. Jika kamu menemukan bahwa proses penahannya adalah web server seperti Nginx, kamu cukup memerintahkan proses tersebut untuk me-reload konfigurasinya atau membuka kembali file log barunya:
BASH
systemctl reload nginx
Jika kamu sedang menelusuri kendala konfigurasi web server yang berkaitan dengan log akses dan error, alur pelacakan serupa juga sering dibahas saat mendiagnosis kendala koneksi hulu, seperti pada panduan Membaca Log Nginx dan PHP-FPM untuk Melacak Sumber Error 502. Ketika layanan menerima sinyal reload (atau sinyal USR1 untuk membuka ulang log), proses utama akan menutup file descriptor lama yang sudah terhapus dan membuat file baru di direktori yang ditentukan. Begitu file descriptor lama tertutup, kernel langsung membebaskan blok data ke superblock, dan angka pada df -h seketika kembali normal.
Ada kalanya proses yang menahan file adalah aplikasi pihak ketiga atau proses kustom yang tidak memiliki mekanisme reload anggun (graceful reload), dan mematikannya akan memutus transaksi yang sedang berjalan. Pada skenario ini, kamu bisa memotong isi file (truncate) menjadi nol byte langsung melalui antarmuka sistem file /proc. Di Linux, setiap proses memiliki direktori di /proc/<PID>/fd/ yang memuat tautan simbolik ke semua file descriptor yang sedang dibukanya. Temukan PID dan nomor FD dari keluaran lsof sebelumnya. Misalnya, jika PID bernilai 1234 dan FD bernilai 3w (angka 3 dengan hak tulis), kamu bisa mengosongkan alokasi bloknya menggunakan perintah pengalihan shell sederhana:
BASH
: > /proc/1234/fd/3
Tanda titik dua (:) adalah operasi no-op di shell. Perintah di atas membuka file descriptor yang masih aktif tersebut dalam mode write-truncate, yang memaksa kernel memangkas ukuran file menjadi 0 byte tanpa memutuskan koneksi proses aplikasi. Kapasitas penyimpanan di df akan langsung kembali lega dalam hitungan detik, sementara aplikasi tetap dapat terus beroperasi tanpa gangguan.
Mengetahui cara mengatasi file descriptor tertahan memang penting saat insiden terjadi, tetapi mengubah kebiasaan administrasi sistem jauh lebih berharga untuk mencegahnya berulang. Kebiasaan pertama adalah tidak pernah menggunakan rm secara terburu-buru pada file log yang sedang aktif ditulis. Jika kamu butuh mengosongkan log berukuran masif dengan segera, lakukan truncation terlebih dahulu sebelum menghapus filenya:
BASH
> /var/log/nama_aplikasi.log
atau menggunakan utilitas khusus:
BASH
truncate -s 0 /var/log/nama_aplikasi.log
Dengan memotong ukuran file menjadi nol byte selagi file tersebut masih terhubung ke namanya di direktori, ukuran blok data di disk akan dilepaskan seketika oleh kernel tanpa merusak file descriptor milik aplikasi. Kebiasaan kedua adalah memastikan utilitas rotasi log seperti logrotate sudah terkonfigurasi dengan benar. Pastikan konfigurasi rotasi menyertakan skrip postrotate yang mengirimkan sinyal pembukaan ulang file log (seperti perintah reload atau sinyal HUP/USR1) kepada daemon terkait, atau gunakan opsi copytruncate jika aplikasi tidak mendukung sinyal pembukaan log baru. Dengan rotasi otomatis yang terawat, kamu tidak perlu lagi masuk ke terminal hanya untuk menghapus log secara manual di tengah kepanikan kapasitas disk yang kritis. Ketika indikator ruang simpan menolak turun setelah file berukuran besar dihapus, jangan tergesa-gesa menyalahkan sistem file atau merestart mesin. Buka daftar proses penahan menggunakan lsof, periksa proses mana yang masih mengantongi file descriptor terbuka, lalu kosongkan isinya atau kirimkan sinyal reload agar kernel bisa mengembalikan alokasi blok data tersebut ke tempat semestinya.