Mengurangi ukuran file database MongoDB

165

Saya punya database MongoDB yang dulunya besar (> 3GB). Sejak itu, dokumen telah dihapus dan saya mengharapkan ukuran file database berkurang.

Tapi karena MongoDB terus mengalokasikan ruang, file-nya masih besar.

Saya membaca di sini dan di sana bahwa perintah admin mongod --repairdigunakan untuk membebaskan ruang yang tidak digunakan, tetapi saya tidak memiliki cukup ruang pada disk untuk menjalankan perintah ini.

Apakah Anda tahu cara saya bisa membebaskan ruang yang tidak digunakan?

Meuble
sumber
7
Apakah pertanyaan ini dianggap terjawab? Apakah kita memerlukan lebih banyak data?
Gates VP
2
dimulai dengan versi 2.8, Anda dapat memampatkan data Anda , yang menghemat banyak ruang.
Salvador Dali
1
Saya memiliki tantangan yang persis sama, cara termudah untuk menyelesaikannya adalah membuat salinan database dengan fungsi copyDatabase (), kemudian ke db.dropDatabase () database asli dan kemudian menyalin database kembali ke tempatnya. database saya sebagian besar kosong dan ketika saya melakukan penyalinan, hanya data yang sebenarnya dapat digunakan yang disalin. menjatuhkan database asli menghapus file besar. menggunakan db.repairDatabase () bukan suatu pilihan karena server saya sudah sangat rendah dalam ruang disk dan operasi ini akan membutuhkan ruang kosong yang sangat besar, jauh lebih dari yang diperlukan untuk operasi ini.
user3892260

Jawaban:

144

UPDATE: dengan compactperintah dan WiredTiger sepertinya ruang disk tambahan benar-benar akan dirilis ke OS .


UPDATE: pada v1.9 + ada compactperintah.

Perintah ini akan melakukan pemadatan "in-line". Masih membutuhkan ruang ekstra, tetapi tidak sebanyak itu.


MongoDB mengkompres file dengan:

  • menyalin file ke lokasi baru
  • mengulangi dokumen dan memesan ulang / memecahkannya
  • mengganti file asli dengan file baru

Anda dapat melakukan ini "kompresi" dengan menjalankan mongod --repairatau dengan menghubungkan langsung dan berjalan db.repairDatabase().

Dalam kedua kasus Anda membutuhkan ruang di suatu tempat untuk menyalin file. Sekarang saya tidak tahu mengapa Anda tidak memiliki cukup ruang untuk melakukan kompres, namun, Anda memiliki beberapa opsi jika Anda memiliki komputer lain dengan lebih banyak ruang.

  1. Ekspor database ke komputer lain dengan Mongo diinstal (menggunakan mongoexport) dan kemudian Anda dapat mengimpor database yang sama (menggunakan mongoimport). Ini akan menghasilkan database baru yang lebih terkompresi. Sekarang Anda dapat menghentikan mongodpenggantian yang asli dengan file database baru dan Anda siap melakukannya.
  2. Hentikan mongod saat ini dan salin file database ke komputer yang lebih besar dan jalankan perbaikan di komputer itu. Anda kemudian dapat memindahkan file database baru kembali ke komputer asli.

Saat ini tidak ada cara yang baik untuk "kompak di tempat" menggunakan Mongo. Dan Mongo pasti bisa menyedot banyak ruang.

Strategi terbaik saat ini untuk pemadatan adalah dengan menjalankan pengaturan Master-Slave. Anda kemudian dapat memadatkan Slave, membiarkannya mengejar dan mengubahnya. Saya tahu masih sedikit berbulu. Mungkin tim Mongo akan tampil dengan pemadatan yang lebih baik, tapi saya pikir itu bukan yang terbaik dalam daftar mereka. Ruang drive saat ini dianggap murah (dan biasanya demikian).

Gates VP
sumber
Terima kasih Gates VP atas jawaban Anda. Saya sedang memikirkan dua opsi yang Anda sebutkan. Tetapi sebelum melakukan hal-hal seperti itu, saya ingin tahu apakah ada solusi compact in place. Terima kasih lagi.
Meuble
3
Pada hari ini (2010-11-18) Dwight (berbicara di acara MongoDC di Washington, DC) merekomendasikan replikasi / - perbaiki / beralih pendekatan jika Anda ingin kompak tanpa mengambil database Anda offline.
David J.
10
Hanya sebuah kepala 'jangan lakukan seperti yang saya lakukan' dan jalankan - perbaiki sebagai root. chowns file db untuk di-root. doh.
Totoro
18
Dokumentasi untuk 'compact' mengatakan: "Operasi ini tidak akan mengurangi jumlah ruang disk yang digunakan pada sistem file." Saya tidak mengerti bagaimana ini merupakan solusi untuk pertanyaan awal.
Ed Norris
Jika Anda melihat pertanyaan awal, bagian dari masalah yang terlibat memiliki terlalu banyak data untuk melakukan perbaikan. Jika Anda telah mengisi 2/3 drive Anda dengan satu DB, Anda tidak dapat melakukan perbaikan. File yang baru dialokasikan akan menyedot ruang yang tersisa sebelum DB yang baru sepenuhnya "disalin & diperbaiki" dan "peralihan" tidak akan pernah terjadi. Dengan compact, setidaknya dia bisa menyimpan file yang ada di tempatnya. Saya setuju, ini bukan solusi lengkap, tetapi ini merupakan peningkatan tambahan.
Gates VP
39

Saya memiliki masalah yang sama, dan diselesaikan dengan hanya melakukan ini di baris perintah:

mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename
pengguna435943
sumber
pernyataan: 15936 Membuat koleksi db.collection gagal. Errmsg: exception: sebutkan ukuran: <n> saat capped benar
tweak2
: Sepertinya regresi ubuntu ... file dump telah metadata telah ditutup: "undefined" di dalamnya ... menghapus perbaikan ini masalah impor.
tweak2
2
Basis data saya telah mencetak hampir seluruh disk. itu 120 GB (disk 160 GB) Compact tidak mengurangi ukuran file dan memperbaiki Database tidak mungkin karena kurangnya ruang. Setelah mongodump & dropDatabase & mongorestore dari db saya memiliki ukuran basis data 40 GB.
Igor Benikov
Koreksi kecil ke perintah pemulihanmongorestore --db databasename dump/databasename
JERRY
34

Sepertinya Mongo v1.9 + memiliki dukungan untuk compact di tempatnya!

> db.runCommand( { compact : 'mycollectionname' } )

Lihat dokumen di sini: http://docs.mongodb.org/manual/reference/command/compact/

"Tidak seperti repair Database, perintah kompak tidak memerlukan ruang disk ganda untuk melakukan tugasnya. Perintah ini membutuhkan sejumlah kecil ruang tambahan saat bekerja. Selain itu, compact lebih cepat."

menunggu
sumber
3
@AnujGupta "Perintah repairDatabase memadatkan semua koleksi dalam database. Ini identik dengan menjalankan perintah kompak pada setiap koleksi secara individual." docs.mongodb.org/manual/reference/command/repairDatabase/… . Jadi jika database perbaikan mengurangi ukuran sehingga kompak. Saya telah memadatkan koleksi saya dengan banyak penghapusan dan pembaruan setiap minggu. Saya suka compact lebih dari repariDatabase karena pertama-tama ini ditargetkan untuk koleksi yang Anda inginkan bukan seluruh database. Kedua itu hanya membutuhkan ruang kosong 2GB bukannya x2 dari filesize db Anda (dalam kasus saya 500GB).
Maziyar
1
Btw lihat ini: "MongoDB menyediakan 2 cara berbeda untuk memadatkan data Anda dan mengembalikan kinerja yang optimal: repairDatabase dan compact. RepairDatabase cocok jika basis data Anda relatif kecil, atau Anda dapat mengambil simpul dari rotasi untuk waktu yang cukup lama. Untuk ukuran basis data dan beban kerja kueri kami, lebih masuk akal untuk menjalankan pemadatan berkelanjutan pada semua koleksi kami. " blog.parse.com/2013/03/26/always-be-compacting github.com/ParsePlatform/Ops/blob/master/tools/mongo_compact.rb
Maziyar
3
@Maziyar docs.mongodb.org/manual/reference/command/compact/#disk-space - "Tidak seperti repairDatabase, compact tidak membebaskan ruang pada sistem file".
Anuj Gupta
4
@Maziyar OP ingin membebaskan ruang yang tidak digunakan , yang dicapai melalui repairDatabase, bukan compact. compacttidak membebaskan ruang, itu hanya mendefrag ruang yang digunakan, yang tidak menguranginya.
Anuj Gupta
5
Pada mongo 3.0, compact akan mendapatkan kembali ruang jika menggunakan mesin penyimpanan WiredTiger.
Gary
19

Kompak semua koleksi dalam database saat ini

db.getCollectionNames().forEach(function (collectionName) {
    print('Compacting: ' + collectionName);
    db.runCommand({ compact: collectionName });
});
OzzyCzech
sumber
13

Jika Anda perlu menjalankan perbaikan penuh, gunakan repairpathopsi. Arahkan ke disk dengan lebih banyak ruang yang tersedia.

Misalnya, pada Mac saya, saya telah menggunakan:

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair

Pembaruan: Per MongoDB Core Server Ticket 4266 , Anda mungkin perlu menambahkan --nojournaluntuk menghindari kesalahan:

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal
David J.
sumber
1
Ini bekerja dengan baik. Saya tidak memiliki ruang 2x yang diperlukan untuk memperbaiki di tempat, jadi saya memasang NAS. Hanya masalah, butuh 18 jam untuk menyelesaikan, tetapi berhasil. Pastikan untuk menambahkan bendera --nojoural.
zenocon
11

Mulai dengan versi 2.8 Mongo, Anda dapat menggunakan kompresi . Anda akan memiliki 3 level kompresi dengan mesin WiredTiger, mmap (yang defaultnya di 2.6 tidak memberikan kompresi):

Berikut adalah contoh seberapa banyak ruang yang dapat Anda hemat untuk data 16 GB:

masukkan deskripsi gambar di sini

data diambil dari artikel ini .

Salvador Dali
sumber
7

Kita perlu memecahkan 2 cara, berdasarkan StorageEngine.

1. mesin MMAP ():

perintah: db.repairDatabase ()

CATATAN: repairDatabase membutuhkan ruang disk kosong sama dengan ukuran kumpulan data Anda saat ini ditambah 2 gigabyte. Jika volume yang menahan dbpath tidak memiliki ruang yang cukup, Anda dapat memasang volume terpisah dan menggunakannya untuk perbaikan. Saat memasang volume terpisah untuk repairDatabase Anda harus menjalankan repairDatabase dari baris perintah dan menggunakan --repairpath untuk menentukan folder tempat menyimpan file perbaikan sementara. misal: Imagine DB size artinya 120 GB, (120 * 2) +2 = 242 GB ruang Hard Disk diperlukan.

cara lain Anda melakukan pengumpulan bijaksana, perintah: db.runCommand ({compact: 'collectionName'})

2. WiredTiger: Secara otomatis diselesaikan sendiri.

Karthickkumar Nagaraj
sumber
6

Ada beberapa kebingungan yang cukup besar tentang reklamasi ruang di MongoDB, dan beberapa praktik yang disarankan benar-benar berbahaya untuk dilakukan dalam jenis penyebaran tertentu. Lebih detail di bawah ini:

TL; DR repairDatabase berupaya untuk menyelamatkan data dari penyebaran MongoDB mandiri yang mencoba untuk pulih dari kerusakan disk. Jika ruang pulih, itu murni efek samping . Memulihkan ruang seharusnya tidak menjadi pertimbangan utama untuk berlari repairDatabase.

Memulihkan ruang dalam node mandiri

WiredTiger: Untuk node mandiri dengan WiredTiger, menjalankan compactakan melepaskan ruang ke OS, dengan satu peringatan: compactPerintah pada WiredTiger di MongoDB 3.0.x dipengaruhi oleh bug ini: SERVER-21833 yang diperbaiki di MongoDB 3.2.3. Sebelum versi ini, compactpada WiredTiger bisa gagal secara diam-diam.

MMAPv1: Karena cara kerja MMAPv1, tidak ada metode yang aman dan didukung untuk memulihkan ruang menggunakan mesin penyimpanan MMAPv1. compactdi MMAPv1 akan mendefrag file data, berpotensi membuat lebih banyak ruang tersedia untuk dokumen baru, tetapi tidak akan melepaskan ruang kembali ke OS.

Anda mungkin dapat menjalankannya repairDatabasejika Anda sepenuhnya memahami konsekuensi dari perintah yang berpotensi berbahaya ini (lihat di bawah), karena repairDatabasepada dasarnya menulis ulang seluruh database dengan membuang dokumen yang rusak. Sebagai efek samping, ini akan membuat file data MMAPv1 baru tanpa ada fragmentasi dan melepaskan ruang kembali ke OS.

Untuk metode yang tidak terlalu berani, menjalankan mongodumpdan mongorestoredimungkinkan juga dalam penerapan MMAPv1, tergantung pada ukuran penerapan Anda.

Memulihkan ruang dalam set replika

Untuk konfigurasi set replika, metode terbaik dan teraman untuk memulihkan ruang adalah dengan melakukan sinkronisasi awal , untuk WiredTiger dan MMAPv1.

Jika Anda perlu memulihkan ruang dari semua node di set, Anda dapat melakukan sinkronisasi awal bergulir. Yaitu, lakukan sinkronisasi awal pada masing-masing sekunder, sebelum akhirnya mundur primer dan lakukan sinkronisasi awal di atasnya. Menggulir metode sinkronisasi awal adalah metode paling aman untuk melakukan pemeliharaan set replika, dan juga tidak melibatkan downtime sebagai bonus.

Harap dicatat bahwa kelayakan melakukan sinkronisasi awal bergulir juga tergantung pada ukuran penempatan Anda. Untuk penyebaran yang sangat besar, mungkin tidak layak untuk melakukan sinkronisasi awal, dan karenanya opsi Anda agak lebih terbatas. Jika WiredTiger digunakan, Anda mungkin dapat mengambil satu sekunder dari set, mulai sebagai standalone, jalankan compactdi atasnya, dan bergabung kembali ke set.

Mengenai repairDatabase

Tolong jangan dijalankan repairDatabasepada set node replika . Ini sangat berbahaya, seperti yang disebutkan dalam halaman database Repair dan dijelaskan lebih detail di bawah ini.

Namanya repairDatabaseagak menyesatkan, karena perintah tidak berusaha memperbaiki apa pun. Perintah itu dimaksudkan untuk digunakan ketika ada kerusakan disk pada node mandiri , yang dapat menyebabkan dokumen rusak.

The repairDatabaseperintah bisa lebih tepat disebut sebagai "basis data penyelamatan". Yaitu, ini membuat ulang basis data dengan membuang dokumen yang rusak dalam upaya untuk membuat basis data ke dalam keadaan di mana Anda dapat memulainya dan menyelamatkan dokumen yang utuh darinya.

Dalam penyebaran MMAPv1, pembangunan kembali file database melepaskan ruang ke OS sebagai efek samping . Melepaskan ruang ke OS tidak pernah tujuannya.

Konsekuensi repairDatabasepada set replika

Dalam set replika, MongoDB mengharapkan semua node di set untuk berisi data yang identik. Jika Anda menjalankan repairDatabasesimpul set replika, ada kemungkinan simpul tersebut berisi korupsi yang tidak terdeteksi, dan dengan repairDatabasepatuh akan menghapus dokumen yang rusak untuk Anda.

Bisa ditebak, ini membuat simpul yang berisi dataset berbeda dari sisa set. Jika pembaruan terjadi untuk mencapai satu dokumen itu, seluruh rangkaian dapat macet.

Untuk memperburuk keadaan, sangat mungkin bahwa situasi ini bisa tetap tidak aktif untuk waktu yang lama, hanya untuk menyerang tiba-tiba tanpa alasan yang jelas.

kevinadi
sumber
5

Jika sebagian besar data dihapus dari koleksi dan koleksi tidak pernah menggunakan ruang yang dihapus untuk dokumen baru, ruang ini perlu dikembalikan ke sistem operasi sehingga dapat digunakan oleh database atau koleksi lain. Anda perlu menjalankan operasi kompak atau perbaikan untuk mendefrag ruang disk dan mendapatkan kembali ruang kosong yang dapat digunakan.

Perilaku proses pemadatan tergantung pada mesin MongoDB sebagai berikut

db.runCommand({compact: collection-name })

MMAPv1

Operasi pemadatan defragment file data & indeks. Namun, itu tidak melepaskan ruang ke sistem operasi. Operasi ini masih berguna untuk mendefrag dan menciptakan ruang yang lebih berdekatan untuk digunakan kembali oleh MongoDB. Namun, tidak ada gunanya ketika ruang disk kosong sangat rendah.

Diperlukan ruang disk tambahan hingga 2GB selama operasi pemadatan.

Kunci tingkat basis data ditahan selama operasi pemadatan.

WiredTiger

Mesin WiredTiger menyediakan kompresi secara default yang menghabiskan lebih sedikit ruang disk daripada MMAPv1.

Proses ringkas melepaskan ruang kosong ke sistem operasi. Ruang disk minimal diperlukan untuk menjalankan operasi ringkas. WiredTiger juga memblokir semua operasi pada basis data karena memerlukan kunci tingkat basis data.

Untuk mesin MMAPv1 , compact doest tidak mengembalikan ruang ke sistem operasi. Anda harus menjalankan operasi perbaikan untuk melepaskan ruang yang tidak digunakan.

db.runCommand({repairDatabase: 1})
VISHAL KUMAWAT
sumber
3

Mongodb 3.0 dan lebih tinggi memiliki mesin penyimpanan baru - WiredTiger. Dalam kasus saya beralih mesin mengurangi penggunaan disk dari 100 Gb menjadi 25Gb.

Hett
sumber
1

Ukuran file basis data tidak dapat dikurangi. Saat "memperbaiki" database, hanya dimungkinkan bagi server mongo untuk menghapus beberapa file-nya. Jika sejumlah besar data telah dihapus, server mongo akan "melepaskan" (menghapus), selama perbaikan, beberapa file yang ada.

ivankoni
sumber
1

Secara umum compact lebih baik daripada memperbaiki Database. Tetapi satu keuntungan dari perbaikan dibandingkan yang ringkas adalah Anda dapat mengeluarkan perbaikan ke seluruh kluster. kompak Anda harus masuk ke setiap beling, yang agak menjengkelkan.

pengguna2077221
sumber
1

Ketika saya memiliki masalah yang sama, saya menghentikan server mongo saya dan mulai lagi dengan perintah

mongod --repair

Sebelum menjalankan operasi perbaikan, Anda harus memeriksa apakah Anda memiliki cukup ruang kosong pada HDD Anda (min - adalah ukuran database Anda)

Alexander Makarov
sumber
1

Untuk mode mandiri Anda dapat menggunakan compact atau perbaikan,

Untuk kumpulan sharded atau set replika, dalam pengalaman saya, setelah Anda menjalankan compact pada primer, diikuti oleh compact sekunder, ukuran basis data primer berkurang, tetapi bukan sekunder. Anda mungkin ingin melakukan resync member untuk mengurangi ukuran basis data sekunder. dan dengan melakukan ini, Anda mungkin menemukan bahwa ukuran database sekunder bahkan lebih berkurang daripada yang utama, saya kira perintah kompak tidak benar-benar memadatkan koleksi. Jadi, saya akhirnya beralih primer dan sekunder dari set replika dan melakukan resync anggota lagi.

kesimpulan saya adalah, cara terbaik untuk mengurangi ukuran set sharded / replika adalah dengan melakukan anggota sinkronisasi, beralih primer sekunder, dan menyinkronkan lagi.

wism
sumber
0

mongoDB -perbaikan tidak disarankan dalam kasus cluster yang diarsir.

Jika menggunakan cluster sharded set replika, gunakan perintah kompak, itu akan menulis ulang dan mendefrag semua file data dan indeks semua koleksi. sintaksis:

db.runCommand( { compact : "collection_name" } )

bila digunakan dengan paksa: true, compact dijalankan berdasarkan set replika utama. misalnya db.runCommand ( { command : "collection_name", force : true } )

Poin lain yang perlu dipertimbangkan: -Memblokir operasi. sangat disarankan untuk dieksekusi di jendela maintenance. -Jika set replika berjalan pada server yang berbeda, perlu dieksekusi pada setiap anggota secara terpisah - Dalam kasus sharded cluster, kompak perlu dijalankan pada setiap anggota beling secara terpisah. Tidak dapat mengeksekusi terhadap instance mongo.

Getah
sumber
-5

Hanya satu cara yang bisa saya lakukan. Tidak ada jaminan keamanan data Anda saat ini. Coba dengan risiko Anda sendiri.

Hapus file data secara langsung dan mulai ulang mongod.

Misalnya, dengan ubuntu (jalur default ke data: / var / lib / mongodb), saya memiliki beberapa file dengan nama seperti: koleksi. #. Saya menyimpan koleksi.0 dan menghapus yang lainnya.

Tampaknya cara yang lebih mudah jika Anda tidak memiliki data serius dalam database.

frnkxiao
sumber
file-file tersebut disimpan sebagai <database_name>. <number> misalnya mydb.3 - Anda tidak dapat memberi tahu koleksi tersebut.
bobmarksie