Operasi data seperti penyisipan, pembaruan, dan penghapusan menghasilkan fragmen disk seiring waktu. Topik ini menjelaskan cara menggunakan perintah compact untuk memulihkan fragmen disk dan meningkatkan pemanfaatan disk. Perintah ini dapat digunakan untuk memulihkan fragmen dari node primer dan sekunder.
Gunakan fitur analisis penyimpanan untuk mereklaim fragmen disk. Metode ini lebih mudah dilakukan di konsol dan memiliki dampak yang lebih kecil pada layanan Anda. Fitur analisis penyimpanan hanya mereklaim fragmen dari node tersembunyi. Untuk mereklaim fragmen dari node primer dan sekunder, Anda harus terlebih dahulu melakukan failover primer/sekunder.
Berikut adalah versi MongoDB yang mendukung penggunaan fitur analisis penyimpanan untuk mereklaim fragmen disk:
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
Cadangan Data: Sebelum mereklaim fragmen disk, cadangkan database Anda.
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>memadatkan data dan mereklaim ruang dari fragmentasi disk.Pemblokiran Baca/Tulis dan Dampak Performa
Pada versi sebelum MongoDB 4.4, menjalankan perintah
compactmengunci database yang berisi koleksi dan memblokir semua operasi baca dan tulis pada database tersebut. Jika terdapat fragmentasi berlebihan, perintahcompactdapat memakan waktu lama untuk dijalankan. Hal ini menciptakan risiko latensi replikasi tinggi pada node tersembunyi. Kami menyarankan Anda menjalankan operasi ini selama jam non-puncak. Jika diperlukan, Anda dapat meningkatkan ukuran Oplog berdasarkan beban kerja tulis Anda atau tingkatkan versi utama database ke MongoDB 4.4 atau yang lebih baru.Pada MongoDB 4.4 dan yang lebih baru, perintah
compacttidak memblokir operasi baca dan tulis. Namun, perintah ini dapat memengaruhi performa selama eksekusi. Kami menyarankan Anda menjalankan operasi ini selama jam non-puncak.
Pembangunan Ulang Node
Untuk instans yang menjalankan MongoDB 3.4, MongoDB 4.0, versi minor MongoDB 4.2 hingga 4.0.22, atau versi minor MongoDB 4.4 hingga 5.0.6, node yang menjalankan perintah
compactmasuk ke status RECOVERING. Jika node tetap dalam status ini terlalu lama, komponen pemeriksaan kesehatan instans menganggap node tersebut tidak sehat dan memicu operasi pembangunan ulang. Untuk informasi lebih lanjut tentang versi MongoDB, lihat Catatan Rilis Versi Minor MongoDB.Untuk instans MongoDB versi yang lebih baru, node yang menjalankan perintah
compacttetap dalam status SECONDARY dan tidak memicu operasi pembangunan ulang.
Perintah
compactTidak Valid:Perintah
compactmungkin gagal dalam skenario berikut. Untuk informasi lebih lanjut, lihat block_compact.Ukuran fisik koleksi kurang dari 1 MB.
Tingkat fragmentasi kurang dari 20%.
Kurang dari 20% dari 80% pertama ruang penyimpanan file tidak digunakan. Kurang dari 10% dari 90% pertama ruang penyimpanan file tidak digunakan.
Waktu Reklamasi: Waktu yang diperlukan untuk mereklaim fragmen disk dengan menjalankan perintah
compactbergantung pada faktor-faktor seperti jumlah data dalam koleksi dan beban sistem.Catatan Lainnya:
Saat menjalankan perintah
compact, ruang penyimpanan yang dilepaskan mungkin lebih kecil daripada ruang penyimpanan yang tidak digunakan. Jika ini terjadi, pastikan perintahcompactsebelumnya selesai sebelum memulai yang berikutnya. Hindari menjalankan perintah ini berulang kali.Perintah
compactdapat dijalankan ketika instans terkunci karena disk penuh.
Informasi latar belakang
Mengapa fragmen disk terbentuk?
Pembentukan: Saat Anda menghapus data dari instans ApsaraDB for MongoDB, ruang penyimpanan yang digunakan oleh data tersebut ditandai sebagai tidak digunakan. Data baru dapat disimpan langsung di ruang kosong ini atau file penyimpanan diperpanjang untuk menyimpan data baru di akhir file. Dalam kasus-kasus ini, beberapa ruang penyimpanan yang tidak digunakan mungkin tidak terpakai kembali, sehingga menciptakan fragmen disk.
Dampak: Banyaknya fragmen disk menurunkan pemanfaatan disk yang efektif. Sebagai contoh, jika ukuran disk adalah 100 GB, fragmen menempati 20 GB, dan data bisnis menempati 60 GB, pemanfaatan disk dari instans database adalah 80%. Namun, pemanfaatan disk yang efektif hanya 60%.
Kapan harus mereklaim fragmen disk
Menghapus Sejumlah Besar Data Sekaligus
Setelah Anda menghapus sejumlah besar data, ruang disk yang sebelumnya diduduki oleh data tersebut tidak segera dikembalikan ke sistem operasi. Ruang ini disediakan untuk penulisan di masa mendatang, yang dapat menyebabkan banyak ruang terfragmentasi di disk yang tidak digunakan secara efektif.
PentingBaik penghapusan data manual maupun mekanisme kedaluwarsa otomatis (TTL) tidak memicu reklamasi fragmen disk secara otomatis. Anda harus mereklaim fragmen disk secara manual.
Menjalankan Beban Kerja Tulis Tinggi untuk Waktu yang Lama
Jika instans Anda menjalankan beban kerja tulis tinggi untuk waktu yang lama, seperti operasi sisip, pembaruan, dan penghapusan yang sering, jumlah ruang terfragmentasi di disk akan meningkat seiring waktu, mengakibatkan akumulasi banyak fragmen disk.
Ruang Disk Rendah dan Fragmentasi Melebihi 20%
Saat ruang disk dari instans database Anda rendah, misalnya, ketika pemanfaatan disk mencapai 85% hingga 90% atau lebih tinggi, mereklaim fragmen disk dapat membebaskan ruang yang ditempati oleh fragmen. Hal ini mengurangi pemanfaatan disk dan mengurangi tekanan pada ruang disk.
Lihat ruang penyimpanan disk
Lihat status penyimpanan koleksi tertentu
Anda dapat menjalankan perintah db.runCommand({collStats: <collection_name>}) untuk melihat status penyimpanan koleksi tertentu. Berikut adalah penjelasan beberapa kata kunci:
size: Ukuran penyimpanan logis dari koleksi.storageSize: Ukuran penyimpanan fisik dari koleksi.freeStorageSize: Ukuran ruang penyimpanan kosong dalam fragmen disk yang dapat direklaim. Kata kunci ini didukung pada ApsaraDB for MongoDB 4.4 dan versi lebih baru.
Setelah menjalankan perintah remove untuk menghapus dokumen, nilai size akan berkurang, tetapi nilai storageSize tidak selalu berkurang. Anda dapat mengamati rasio freeStorageSize terhadap storageSize. Rasio yang lebih tinggi menunjukkan tingkat fragmentasi disk yang lebih tinggi.
Untuk informasi lebih lanjut tentang kata kunci size, storageSize, dan freeStorageSize, lihat collStats-Output.
Estimasi ruang fragmen disk yang akan direklaim
Hubungkan ke instans ApsaraDB for MongoDB menggunakan mongo shell. Untuk instans set replika, hubungkan ke node sekunder untuk meminimalkan dampak pada layanan Anda. Metode koneksi untuk tipe instans yang berbeda adalah sebagai berikut:
Beralih ke database yang berisi koleksi.
Sintaks:
use <database_name>Parameter:
<database_name>adalah nama database yang berisi koleksi.CatatanAnda dapat menjalankan perintah
show dbsuntuk menanyakan database yang ada.Contoh:
Beralih ke database test_database.
use test_databaseLihat ruang fragmen disk yang akan direklaim untuk koleksi.
Sintaks:
db.<collection_name>.stats().wiredTiger["block-manager"]["file bytes available for reuse"]Parameter:
<collection_name>adalah nama koleksi.CatatanAnda dapat menjalankan perintah
show tablesuntuk menanyakan koleksi yang ada.Contoh:
db.test_database_collection.stats().wiredTiger["block-manager"]["file bytes available for reuse"]Hasilnya adalah sebagai berikut:
207806464Output ini menunjukkan bahwa ruang fragmen disk yang dapat direklaim diperkirakan sebesar 207.806.464 byte.
Reklaim ruang disk yang terfragmentasi
Instans mandiri atau set replika
Instans mandiri hanya memiliki satu node. Untuk mereklaim fragmen disk, hubungkan ke node tersebut dan jalankan perintah
compact.Instans set replika terdiri dari beberapa node. Anda harus melakukan operasi reklamasi pada node primer dan sekunder.
PentingUntuk meminimalkan dampak pada layanan, pertama-tama reklaim fragmen dari node sekunder. Kemudian, lakukan failover primer/sekunder untuk mengubah node primer menjadi node sekunder dan mereklaim fragmen dari node sekunder baru. Untuk informasi lebih lanjut tentang cara melakukan failover primer/sekunder, lihat Konfigurasikan Failover Primer/Sekunder untuk Instans Set Replika.
Jika instans set replika memiliki node read-only, Anda juga harus mereklaim fragmen disk dari node tersebut. Perintah yang dijalankan sama dengan yang digunakan untuk mereklaim fragmen dari node primer dan sekunder.
Hubungkan ke instans mandiri atau set replika menggunakan mongo shell. Metode koneksi untuk tipe instans berbeda adalah sebagai berikut:
Beralih ke database yang berisi koleksi.
Sintaks:
use <database_name>Parameter:
<database_name>adalah nama database yang berisi koleksi.CatatanAnda dapat menjalankan perintah
show dbsuntuk menanyakan database yang tersedia.Contoh:
Beralih ke database replica_database.
use replica_databaseLihat ruang disk yang ditempati oleh database sebelum mereklaim fragmen disk.
db.stats()CatatanAnda dapat menyalin dan menjalankan perintah ini secara langsung tanpa modifikasi.
Reklaim fragmen disk dari koleksi.
Sintaks:
db.runCommand({compact:"<collection_name>",force:true})Parameter:
<collection_name>: Nama koleksi.CatatanAnda dapat menjalankan perintah
show tablesuntuk menanyakan koleksi yang tersedia.force: Opsional. Nilainya tetap true.Parameter ini diperlukan jika Anda menjalankan perintah ini pada node primer instans ApsaraDB for MongoDB versi 4.2 atau lebih lama.
Contoh:
db.runCommand({compact:"sharded_collection"})Operasi yang berhasil mengembalikan hasil berikut:
{ "ok" : 1 }Lihat ruang disk yang ditempati oleh database setelah mereklaim fragmen disk.
db.stats()CatatanAnda dapat menyalin dan menjalankan perintah ini secara langsung tanpa modifikasi.
Instans kluster sharded
Untuk instans kluster sharded, Anda hanya perlu mereklaim fragmen disk dari node yang sesuai di komponen shard. Komponen Mongos dan Configserver tidak menyimpan data pengguna. Mereka juga memiliki lebih banyak operasi sisip dan pembaruan serta lebih sedikit operasi penghapusan. Oleh karena itu, Anda tidak perlu mereklaim fragmen disk mereka.
Perintah compact tidak didukung pada node read-only instans kluster sharded. Oleh karena itu, Anda tidak dapat mereklaim fragmen disk dari node read-only.
Hubungkan ke instans kluster sharded menggunakan mongo shell. Untuk informasi lebih lanjut, lihat Hubungkan ke Instans Kluster Sharded MongoDB Menggunakan Mongo Shell.
Beralih ke database yang berisi koleksi.
Sintaks:
use <database_name>Parameter:
<database_name>adalah nama database yang berisi koleksi.CatatanAnda dapat menjalankan perintah
show dbsuntuk menanyakan database yang tersedia.Contoh:
Beralih ke database sharded_database.
use sharded_databaseLihat ruang disk yang ditempati oleh database sebelum mereklaim fragmen disk.
db.stats()CatatanAnda dapat menyalin dan menjalankan perintah ini secara langsung tanpa modifikasi.
Reklaim fragmen disk dari koleksi.
Anda harus melakukan operasi reklamasi pada node primer dan sekunder di komponen shard.
PentingUntuk meminimalkan dampak pada layanan, pertama-tama reklaim fragmen dari node sekunder. Kemudian, lakukan failover primer/sekunder untuk mengubah node primer menjadi node sekunder dan mereklaim fragmen dari node sekunder baru. Untuk informasi lebih lanjut tentang cara melakukan failover primer/sekunder, lihat Konfigurasikan Failover Primer/Sekunder untuk Instans Kluster Sharded.
Reklaim fragmen disk dari node sekunder di komponen shard.
Eksekusi operasi ini berbeda antara mongo shell dan mongosh. Pilih metode yang sesuai dengan klien Anda.
CatatanDibandingkan dengan mongosh 1.x, mongosh 2.x menambahkan dukungan untuk pengaturan parameter preferensi baca. Untuk informasi lebih lanjut, lihat Preferensi Baca.
mongo shell
Sintaks:
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"},$queryOptions: {$readPreference: {mode: 'secondary'}}})Parameter:
<Shard ID>: ID komponen shard.CatatanMasuk ke Konsol MongoDB. Di halaman Basic Information instans target, Anda dapat menemukan ID shard di bagian Shard List.
<collection_name>: Nama koleksi.CatatanAnda dapat menjalankan perintah
show tablesuntuk menanyakan koleksi yang tersedia.
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.CatatanMasuk ke Konsol MongoDB. Di halaman Basic Information instans target, Anda dapat melihat ID shard di bagian Shard List.
<collection_name>: Nama koleksi.CatatanAnda dapat menjalankan perintah
show tablesuntuk menanyakan koleksi yang tersedia.
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.CatatanMasuk ke Konsol MongoDB. Di halaman Basic Information instans target, Anda dapat menemukan ID shard di bagian Shard List.
<collection_name>: Nama koleksi.CatatanAnda dapat menjalankan perintah
show tablesuntuk menanyakan koleksi yang tersedia.
Contoh:
db.runCommand({runCommandOnShard:"d-2ze657bce53fb6d4","command":{compact:"test_collection"}}, { readPreference: "secondary" })Reklaim fragmen disk dari node primer di komponen shard.
Sintaks:
db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>",force:true}})Parameter:
<Shard ID>: ID komponen shard.CatatanMasuk ke Konsol MongoDB. Di halaman Basic Information instans target, temukan ID shard di bagian Shard List.
<collection_name>: Nama koleksi.CatatanAnda dapat menjalankan perintah
show tablesuntuk menanyakan koleksi yang tersedia.force: Opsional. Nilainya tetap true.Parameter ini diperlukan jika instans kluster sharded Anda adalah versi 4.2 atau lebih lama.
Contoh:
db.runCommand({runCommandOnShard:"shard01","command":{compact:"sharded_collection",force:true}})
Lihat ruang disk yang ditempati oleh database setelah mereklaim fragmen disk.
db.stats()CatatanAnda dapat menyalin dan menjalankan perintah ini secara langsung tanpa modifikasi.
FAQ
T: Perintah gagal dengan pesan kesalahan "Compaction interrupted on table:xxx due to cache eviction pressure" pada server xxx.
J: Saat menjalankan perintah compact pada instans dengan spesifikasi rendah yang menggunakan versi sebelumnya, perintah tersebut dapat gagal karena tekanan cache. Disarankan untuk menjalankan operasi ini selama jam non-puncak.