Operasi insert, update, dan delete data menghasilkan fragmen disk seiring waktu. Gunakan perintah compact untuk mereclaim fragmen tersebut dari node primary dan secondary serta meningkatkan pemanfaatan disk.
Kami menyarankan menggunakan fitur storage analysis untuk mereclaim fragmen disk. Fitur ini lebih sederhana dan berdampak lebih kecil terhadap layanan. Storage analysis hanya mereclaim fragmen dari node hidden. Untuk mereclaim fragmen dari node primary dan secondary, lakukan terlebih dahulu primary/secondary failover.
Storage analysis tersedia untuk versi MongoDB berikut:
-
MongoDB 8.0: semua versi minor.
-
MongoDB 7.0: semua versi minor.
-
MongoDB 6.0: semua versi minor.
-
MongoDB 5.0: semua versi minor.
-
MongoDB 4.4: 5.0.7 atau yang lebih baru.
-
MongoDB 4.2: 4.0.23 atau yang lebih baru.
Prasyarat
Instans harus menggunakan mesin penyimpanan WiredTiger.
Catatan penggunaan
-
Backup data: Backup database Anda sebelum mereclaim fragmen.
-
Dampak perintah
compact:Perintah
<a data-link-href-cangjie="https://www.mongodb.com/docs/manual/reference/command/compact/#dbcmd.compact" href="https://www.mongodb.com/docs/manual/reference/command/compact/#dbcmd.compact" id="xref_8b5_xj7_jq4" rel="noopener noreferrer" target="_blank">compact</a>menulis ulang dan mendefragmentasi semua data dan indeks dalam sebuah collection untuk memulihkan ruang yang tidak terpakai.-
Pemblokiran baca/tulis dan dampak performa
-
Pada versi sebelum MongoDB 4.4, perintah
compactmengunci database dan memblokir semua operasi baca dan tulis. Koleksi yang sangat terfragmentasi dapat menyebabkan perintahcompactberjalan lama dan meningkatkan latensi replikasi pada node hidden. Lakukan operasi ini selama jam sepi, tingkatkan ukuran oplog, atau upgrade versi utama ke MongoDB 4.4 atau yang lebih baru sebelum mereclaim fragmen. -
Pada MongoDB 4.4 dan yang lebih baru, perintah
compacttidak memblokir operasi baca dan tulis tetapi tetap dapat memengaruhi performa. Lakukan operasi ini selama jam sepi.
-
-
Pembangunan ulang node
-
Untuk MongoDB 3.4, 4.0, 4.2 (4.0.22 atau lebih lama), atau 4.4 (5.0.6 atau lebih lama), node yang menjalankan
compactmasuk ke status RECOVERING. Jika operasi berlangsung terlalu lama, pemeriksaan kesehatan mungkin menganggap node tidak sehat dan memicu node rebuilding. Lihat catatan rilis versi minor MongoDB. -
Pada versi MongoDB yang lebih baru, node yang menjalankan
compacttetap berada dalam status SECONDARY dan tidak memicu pembangunan ulang node.
-
-
-
Perintah
compacttidak efektif:Perintah
compactmungkin tidak efektif dalam skenario berikut (block_compact):-
Ukuran penyimpanan fisik koleksi kurang dari 1 MB.
-
Laju fragmentasi kurang dari 20%.
-
Ruang bebas kurang dari 20% pada 80% pertama file data, atau ruang bebas kurang dari 10% pada 90% pertama file data.
-
-
Waktu reclaim: Waktu eksekusi
compactbergantung pada volume data dan beban sistem. -
Catatan lainnya:
-
Ruang yang direclaim oleh
compactmungkin lebih kecil daripada total ruang bebas. Pastikan operasicompactsebelumnya telah selesai sebelum memulai yang baru. -
Perintah
compactdapat dijalankan meskipun instans terkunci akibat disk space penuh.
-
Informasi latar belakang
Mengapa fragmen disk terjadi?
-
Pembentukan: Saat data dihapus, ruang penyimpanan ditandai sebagai bebas. Data baru dapat menggunakan kembali ruang ini atau ditambahkan di akhir file. Hal ini menciptakan kantong-kantong ruang yang tidak terpakai yang dikenal sebagai fragmen disk.
-
Dampak: Semakin banyak fragmen berarti pemanfaatan disk efektif semakin rendah. Misalnya, pada disk 100 GB dengan 20 GB fragmen dan 60 GB data aktif, pemanfaatan yang dilaporkan adalah 80% (80 GB/100 GB), tetapi pemanfaatan efektif hanya 60% (60 GB/100 GB).
Kapan harus mereclaim fragmen disk
-
Setelah Anda menghapus volume data yang besar
Saat Anda menghapus sejumlah besar dokumen, ruang yang dibebaskan tidak dikembalikan ke sistem operasi tetapi disimpan untuk penulisan di masa depan. Hal ini dapat meninggalkan ruang terfragmentasi yang signifikan pada disk.
PentingBaik penghapusan manual maupun kedaluwarsa TTL tidak secara otomatis mereclaim fragmen disk. Anda harus mereclaim ruang tersebut secara manual.
-
Setelah beban kerja tulis tinggi berkepanjangan
Beban kerja tulis tinggi berkelanjutan (insert, update, dan delete yang sering) secara bertahap mengumpulkan ruang terfragmentasi di seluruh disk.
-
Saat ruang disk hampir habis dan fragmentasi melebihi 20%
Saat pemanfaatan disk mencapai 85% hingga 90% atau lebih, mereclaim fragmen dapat membebaskan ruang dan mengurangi tekanan penyimpanan.
Lihat ruang penyimpanan disk
Lihat status penyimpanan koleksi
Jalankan perintah db.runCommand({collStats: <collection_name>}) untuk melihat status penyimpanan. Bidang output utama:
-
size: Ukuran penyimpanan logis koleksi. -
storageSize: Ukuran penyimpanan fisik koleksi. -
freeStorageSize: Ruang bebas yang dapat direclaim dalam koleksi. Tersedia di MongoDB 4.4 dan yang lebih baru.
Setelah menghapus dokumen dengan perintah remove, nilai size berkurang tetapi storageSize mungkin tidak berubah. Rasio freeStorageSize terhadap storageSize yang tinggi menunjukkan fragmentasi tinggi.
Bidang-bidang ini (size, storageSize, freeStorageSize) didokumentasikan dalam collStats-Output.
Perkirakan ruang yang dapat direclaim
-
Hubungkan ke instans ApsaraDB for MongoDB Anda menggunakan mongo shell. Untuk instans replica set, hubungkan ke node secondary untuk meminimalkan dampak terhadap layanan. Instruksi koneksi:
-
Beralih ke database yang berisi koleksi tersebut.
Sintaks:
use <database_name>Deskripsi parameter:
<database_name>adalah nama database yang berisi koleksi tersebut.CatatanAnda dapat menjalankan perintah
show dbsuntuk menampilkan daftar database yang ada.Contoh:
Beralih ke database test_database.
use test_database -
Periksa jumlah ruang fragmen disk yang dapat direclaim untuk koleksi tersebut.
Sintaks:
db.<collection_name>.stats().wiredTiger["block-manager"]["file bytes available for reuse"]Deskripsi parameter:
<collection_name>adalah nama koleksi tersebut.CatatanAnda dapat menjalankan perintah
show tablesuntuk menampilkan daftar koleksi yang ada.Contoh:
db.test_database_collection.stats().wiredTiger["block-manager"]["file bytes available for reuse"]Hasil berikut dikembalikan:
207806464Output ini menunjukkan bahwa perkiraan ruang yang dapat direclaim adalah 207.806.464 byte.
Reclaim fragmen disk
Instans mandiri atau instans set replika
-
Instans mandiri memiliki satu node. Hubungkan ke node tersebut dan jalankan perintah
compactuntuk mereclaim fragmen disk. -
Instans set replika memiliki beberapa node. Reclaim fragmen dari node primary dan secondary.
Penting-
Untuk meminimalkan dampak terhadap layanan, reclaim fragmen dari node secondary terlebih dahulu. Kemudian lakukan primary/secondary failover dan reclaim fragmen dari node primary sebelumnya (sekarang menjadi secondary).
-
Jika instans set replika memiliki node read-only, reclaim juga fragmen disk-nya. Perintahnya sama seperti untuk node primary dan secondary.
-
-
Hubungkan ke instans menggunakan mongo shell. Instruksi koneksi:
-
Beralih ke database yang berisi koleksi tersebut.
Sintaks:
use <database_name>Deskripsi parameter:
<database_name>adalah nama database yang berisi koleksi tersebut.CatatanAnda dapat menjalankan perintah
show dbsuntuk menampilkan daftar database yang ada.Contoh:
Beralih ke database replica_database.
use replica_database -
Lihat ruang disk yang digunakan oleh database sebelum mereclaim fragmen disk.
db.stats()CatatanAnda dapat menyalin dan menjalankan perintah ini tanpa modifikasi.
-
Reclaim fragmen disk dari koleksi tersebut.
Sintaks:
db.runCommand({compact:"<collection_name>",force:true})Parameter:
-
<collection_name>: Nama koleksi tersebut.CatatanAnda dapat menjalankan perintah
show tablesuntuk menampilkan daftar koleksi yang ada. -
force: Opsional. Nilainya harustrue.Parameter ini wajib jika Anda menjalankan perintah ini pada node primary dari instans ApsaraDB for MongoDB yang menjalankan versi 4.2 atau lebih lama.
Contoh:
db.runCommand({compact:"sharded_collection"})Operasi yang berhasil mengembalikan hasil berikut:
{ "ok" : 1 } -
-
Lihat ruang disk yang digunakan oleh database setelah mereclaim fragmen disk.
db.stats()CatatanAnda dapat menyalin dan menjalankan perintah ini tanpa modifikasi.
Instans kluster sharded
Untuk instans kluster sharded, reclaim fragmen disk hanya dari node shard. Komponen mongos dan config server tidak menyimpan data pengguna, sehingga reclaim fragmen mereka tidak diperlukan.
Perintah compact tidak didukung pada node read-only dari instans kluster sharded.
-
Hubungkan ke instans kluster sharded menggunakan mongo shell. Hubungkan ke instans kluster sharded menggunakan mongo shell.
-
Beralih ke database yang berisi koleksi tersebut.
Sintaks:
use <database_name>Deskripsi parameter:
<database_name>adalah nama database yang berisi koleksi tersebut.CatatanAnda dapat menjalankan perintah
show dbsuntuk menampilkan daftar database yang ada.Contoh:
Beralih ke database sharded_database.
use sharded_database -
Lihat ruang disk yang digunakan oleh database sebelum mereclaim fragmen disk.
db.stats()CatatanAnda dapat menyalin dan menjalankan perintah ini tanpa modifikasi.
-
Reclaim fragmen disk dari koleksi tersebut.
Reclaim fragmen dari node primary dan secondary di setiap shard.
PentingUntuk meminimalkan dampak terhadap layanan, reclaim fragmen dari node secondary terlebih dahulu. Kemudian lakukan primary/secondary failover dan reclaim fragmen dari node primary sebelumnya (sekarang menjadi secondary).
-
Reclaim fragmen disk dari node secondary dalam komponen shard.
Perintah berbeda untuk mongo shell dan mongosh. Pilih tab yang sesuai dengan client Anda.
CatatanMongosh 2.x menambahkan parameter untuk menentukan preferensi baca, tidak seperti mongosh 1.x.
Mongo shell
Sintaks:
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"},$queryOptions: {$readPreference: {mode: 'secondary'}}})Parameter:
-
<Shard ID>: ID komponen shard.CatatanLogin ke Konsol MongoDB. Pada halaman Basic Information instans target, temukan ID komponen shard di bagian Shard List.
-
<collection_name>: Nama koleksi tersebut.CatatanAnda dapat menjalankan perintah
show tablesuntuk menampilkan daftar koleksi yang ada.
Contoh:
db.runCommand({runCommandOnShard:"shard01","command":{compact:"sharded_collection"},$queryOptions: {$readPreference: {mode: 'secondary'}}})Mongosh 1.x
Sintaks:
db.getMongo().setReadPref('secondary') db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"}})Parameter:
-
<Shard ID>: ID komponen shard.CatatanLogin ke Konsol MongoDB. Pada halaman Basic Information instans target, temukan ID komponen shard di bagian Shard List.
-
<collection_name>: Nama koleksi tersebut.CatatanAnda dapat menjalankan perintah
show tablesuntuk menampilkan daftar koleksi yang ada.
Contoh:
db.getMongo().setReadPref('secondary') db.runCommand({runCommandOnShard:"d-2ze91ae9d55d6604","command":{compact:"test"}})Mongosh 2.x
Sintaks:
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"}},{readPreference: "secondary"})Parameter:
-
<Shard ID>: ID komponen shard.CatatanLogin ke Konsol MongoDB. Pada halaman Basic Information instans target, temukan ID komponen shard di bagian Shard List.
-
<collection_name>: Nama koleksi tersebut.CatatanAnda dapat menjalankan perintah
show tablesuntuk menampilkan daftar koleksi yang ada.
Contoh:
db.runCommand({runCommandOnShard:"d-2ze657bce53fb6d4","command":{compact:"test_collection"}}, { readPreference: "secondary" }) -
-
Reclaim fragmen disk dari node primary dalam komponen shard.
Sintaks:
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>",force:true}})Parameter:
-
<Shard ID>: ID komponen shard.CatatanLogin ke Konsol MongoDB. Pada halaman Basic Information instans target, temukan ID komponen shard di bagian Shard List.
-
<collection_name>: Nama koleksi tersebut.CatatanAnda dapat menjalankan perintah
show tablesuntuk menampilkan daftar koleksi yang ada. -
force: Opsional. Nilainya harustrue.Parameter ini wajib jika instans kluster sharded Anda menjalankan versi 4.2 atau lebih lama.
Contoh:
db.runCommand({runCommandOnShard:"shard01","command":{compact:"sharded_collection",force:true}}) -
-
-
Lihat ruang disk yang digunakan oleh database setelah mereclaim fragmen disk.
db.stats()CatatanAnda dapat menyalin dan menjalankan perintah ini tanpa modifikasi.
FAQ
T: Perintah gagal dengan pesan "Compaction interrupted on table:xxx due to cache eviction pressure" pada server xxx.
J: Instans lama dengan spesifikasi kecil mungkin keluar lebih awal selama compact karena tekanan cache. Lakukan operasi ini selama jam sepi.