Disk penuh adalah kegagalan infrastruktur yang menyerang database dengan cara paling langsung: mongod berhenti menulis, lalu berhenti berjalan. Berbeda dari galat query atau koneksi yang punya pesan spesifik, masalah penyimpanan menuntut kita melihat dua dunia sekaligus — berkas fisik di sistem operasi dan angka logis di dalam database. Chapter ini memeriksa keduanya di mesin latihan: sisa ruang lewat df dan db.stats(), efek kompresi WiredTiger lewat perbandingan dataSize versus storageSize, lalu menutup dengan prosedur saat hal terburuk terjadi — disk penuh, izin berkas salah, dan dugaan kerusakan data.
Peta materi Chapter ini:
- Pemeriksaan dua dunia:
df -hdari OS,db.stats()dari dalam database. dataSizeversusstorageSize— kenapa ukuran logis dan fisik berbeda jauh.- Prosedur disk penuh dan masalah izin di
dbPath. - Dugaan kerusakan data: tanda, verifikasi, dan urutan pemulihan yang benar.
Berapa Sisa Ruang: Dua Sudut Pandang #
Dari shell, df -h pada direktori data adalah pemeriksaan pertama:
df -h /home/z/my-project/mongo-dataOutput yang Dihasilkan:
Filesystem Size Used Avail Use% Mounted on
c-6ad366ea-145cf406-1e00df7b3d2b-rootfs 9.9G 2.2G 7.2G 23% /Kolom yang berarti bagi MongoDB: Avail — ruang yang masih bisa ditulis — dan Use% yang merambat naik. Dari dalam database, angka yang sama bisa dibaca tanpa membuka shell, lengkap dengan pemakaian versi MongoDB sendiri. Kita siapkan dulu collection arsip berisi data repetitif sebagai bahan perbandingan:
use latihan_trouble
db.arsip.drop()
const docs = []
for (let i = 0; i < 2000; i++) {
docs.push({ rak: "R" + (i % 20), kategori: "novel", status: "tersedia", catatan: "Stok reguler siap kirim ke seluruh cabang toko", stok: i % 30 })
}
const hasil = db.arsip.insertMany(docs)
print("jumlah document arsip: " + db.arsip.countDocuments({}) + ", acknowledged: " + hasil.acknowledged)
db.stats({ scale: 1024 * 1024 })Output yang Dihasilkan:
switched to db latihan_trouble
true
2000
jumlah document arsip: 2000, acknowledged: true
{
db: 'latihan_trouble',
collections: Long('6'),
views: Long('0'),
objects: Long('7010'),
avgObjSize: 110.55178316690443,
dataSize: 0.7390670776367188,
storageSize: 0.24609375,
indexes: Long('7'),
indexSize: 0.3828125,
totalSize: 0.62890625,
scaleFactor: Long('1048576'),
fsUsedSize: 2696.27734375,
fsTotalSize: 10043.26953125,
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1792279678, i: 5 }),
signature: {
hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
keyId: Long('0')
}
},
operationTime: Timestamp({ t: 1792279678, i: 5 })
}Field fsUsedSize dan fsTotalSize adalah padanan Used dan Size dari df (pembulatannya sedikit berbeda karena satuan MiB versus GiB) — angka ini yang layak dipantau berkala karena berlaku untuk seluruh dbPath, bukan satu database. Baris 2000 sebelum print adalah nilai akhir ekspresi docs.push(...) di loop; baris true di awal adalah hasil drop(). Perhatikan juga indexSize: index ikut memakan disk, dan pada database dengan banyak index, indexSize bisa melebihi storageSize data itu sendiri. Angka objects di sini mencakup seluruh collection latihan kita di database ini.
dataSize versus storageSize: Kompresi WiredTiger #
Pasangan field paling sering disalahpahami: dataSize adalah ukuran logis document seolah tak terkompresi, storageSize adalah ruang fisik yang benar-benar dipakai di disk setelah kompresi block WiredTiger. Kita bedah collection arsip saja:
const s = db.arsip.stats({ scale: 1024 * 1024 })
({ ns: s.ns, jumlah: s.count, dataSize: s.size, storageSize: s.storageSize, totalIndexSize: s.totalIndexSize, totalSize: s.totalSize })Output yang Dihasilkan:
{
ns: 'latihan_trouble.arsip',
jumlah: 2000,
dataSize: 0.27751922607421875,
storageSize: 0.00390625,
totalIndexSize: 0.00390625,
totalSize: 0.0078125
}Dua ribu document berukuran logis 0,28 MB hanya memakan sekitar 4 KB di disk — rasio pemadatan ekstrem karena isinya sangat repetitif (kategori, status, dan catatan yang sama berulang). Data production yang lebih beragam biasanya berada di rasio yang jauh lebih rendah, tetapi arah kesimpulannya sama: ukuran data menurut aplikasi bukan ukuran data menurut disk. Konsekuensinya dua arah: kapasitas tidak bisa dihitung dari estimasi ukuran document mentah, dan storageSize yang jauh di bawah dataSize adalah tanda kompresi bekerja normal — bukan gejala hilangnya data.
Disk Penuh: Ketika mongod Berhenti #
Urutan kejadiannya khas: ruang Avail menyentuh nol, operasi write mulai gagal dengan galat tingkat sistem operasi, WiredTiger menolak melanjutkan tanpa jaminan bisa menulis, dan mongod berhenti — sering kali dengan pesan no space left on device di log sebelum proses keluar. Gejala di production yang perlu dikenali: aplikasi mendadak gagal write di semua collection sekaligus.
Urutan pemulihannya penting. Pertama, pulihkan ruang di luar MongoDB bila ada (log aplikasi yang membengkak, berkas sementara) — jangan pernah menghapus berkas di dalam dbPath secara manual. Kedua, dari dalam database: hapus index tak terpakai (mengembalikan indexSize), terapkan TTL index untuk data kedaluwarsa otomatis, atau jalankan compact pada collection terbesar di jam sepi. Ketiga, bila pertumbuhannya struktural, pindahkan dbPath ke disk lebih besar — prosedurnya dibahas di Section Backup dan Recovery.
dbPath dan Izin Berkas #
mongod membaca-mengubah berkas di dbPath sepanjang hidupnya, jadi izin berkas adalah syarat hidup:
ls -ld /home/z/my-project/mongo-dataOutput yang Dihasilkan:
drwxrwxr-x 5 z z 53248 Oct 17 23:27 /home/z/my-project/mongo-dataPembacaannya mengikuti notasi izin Unix: pemilik z memiliki rwx, grup z juga rwx, dan pengguna lainnya hanya r-x. Pada mesin latihan proses mongod berjalan sebagai pengguna z — cocok dengan pemilik dbPath. Gejala klasik di mesin baru: mongod menolak menyala dengan Permission denied di log karena dbPath dibuat lewat sudo sehingga dimiliki root, sementara service dijalankan user lain. Perbaikannya satu perintah chown — bukan menyalakan ulang berulang kali.
Dugaan Kerusakan Data: Urutan yang Benar #
Tanda-tandanya di log: mongod berhenti tidak wajar (listrik, kill -9), lalu saat dinyalakan ulang ia berulang kali keluar sendiri dengan pesan kerusakan berkas WiredTiger. Sebelum melakukan apa pun selain memverifikasi — satu prinsip: backup dulu, baru perbaiki. Salin seluruh dbPath (dalam keadaan mati) atau mongodump yang masih bisa dibaca, baru kemudian jalankan mongod --repair yang membangun ulang berkas data; perbaikan ini bisa membuang document yang berkasnya rusak, sehingga menjalankannya tanpa backup adalah keputusan yang tidak bisa dibatalkan.
Untuk kecurigaan ringan tanpa gejala berhenti, db.arsip.validate() memeriksa konsistensi struktur, index, dan data sebuah collection lalu melaporkan temuannya — jalankan pada collection yang dicurigai, bukan pada seluruh database. Verifikasi cadangan berkala adalah satu-satunya cara tahu backup benar-benar bisa dipulihkan.
| Gejala | Penyebab umum | Tindakan |
|---|---|---|
| Write gagal di semua collection mendadak | Disk penuh (Avail nol) | Pulihkan ruang; audit indexSize; compact di jam sepi |
mongod tidak mau menyala, log Permission denied | dbPath dimiliki user lain | chown dbPath ke user yang menjalankan mongod |
mongod keluar berulang setelah crash | Kerusakan berkas WiredTiger | Backup dbPath dulu, baru --repair |
storageSize jauh di bawah dataSize | Kompresi WiredTiger normal | Tidak perlu tindakan — itu perilaku yang benar |
| Kapasitas habis meski data “kecil” | Banyak index; data historis menumpuk | Tinjau indexSize; TTL index; arsipkan |
Angka fsUsedSize naik terus tanpa write besar | Journal dan ruang internal belum dikembalikan | Jadwalkan compact; pantau tren, bukan satu titik |
Rangkuman #
- Pemeriksaan penyimpanan selalu dua sisi:
df -hdari OS,db.stats()dari database — keduanya harus cocok. dataSizeadalah ukuran logis,storageSizeukuran fisik pasca-kompresi; selisih besar adalah normal.- Disk penuh dimitigasi dengan urutan aman: pulihkan ruang, hapus index tak terpakai,
compact, lalu pertimbangkan disk lebih besar. - Izin
dbPathyang salah membuatmongodmenolak menyala; perbaikannyachown, bukan restart berulang. - Kerusakan data: backup dulu,
--repairkemudian,validate()untuk kecurigaan ringan.