MongoDB veritabanı dosya boyutunu küçültme


165

Bir zamanlar büyük (> 3GB) bir MongoDB veritabanı var. O zamandan beri, belgeler silindi ve veritabanı dosyalarının boyutunun buna göre azalmasını bekliyordum.

Ancak MongoDB ayrılan alanı koruduğundan dosyalar hala büyüktür.

Burada ve burada admin komutunun mongod --repairkullanılmayan alanı boşaltmak için kullanıldığını okudum , ancak bu komutu çalıştırmak için diskte yeterli alanım yok.

Kullanılmayan alanı serbest bırakabilmemin bir yolunu biliyor musunuz?


7
Bu soru cevaplandı mı? Daha fazla veriye ihtiyacımız var mı?
Gates VP

2
2.8 sürümünden başlayarak verilerinizi sıkıştırarak önemli miktarda alan tasarrufu sağlayabilirsiniz.
Salvador Dali

1
i tam olarak aynı meydan okuma vardı, bunu çözmek için en kolay yolu, copyDatabase () işlevi ile veritabanının bir kopyasını yapmak, sonra db.dropDatabase () özgün veritabanı ve sonra yerine veritabanını kopyalamak oldu. benim veritabanı çoğunlukla boştu ve kopyasını yaptığımda, sadece gerçek kullanılabilir veri kopyalandı. orijinal veritabanını bırakmak büyük dosyaları sildi. db.repairDatabase () kullanmak, sunucumun disk alanı zaten düşük olduğundan ve bu işlem için bu işlem için gerekenden çok daha fazla miktarda boş alan gerektirdiği için bir seçenek değildi.
user3892260

Yanıtlar:


144

GÜNCELLEME: ile compactkomuta ve benzeri WiredTiger görünüyor fazladan disk alanı aslında işletim sistemine çıkacak .


GÜNCELLEME: v1.9 + 'dan itibaren bir compactkomut vardır.

Bu komut "satır içi" sıkıştırma gerçekleştirir. Yine de fazladan alana ihtiyaç duyacak, ama o kadar da değil.


MongoDB dosyaları şu şekilde sıkıştırır:

  • dosyaları yeni bir konuma kopyalama
  • belgeler arasında döngü ve yeniden sıralama / yeniden çözme
  • orijinal dosyaları yeni dosyalarla değiştirme

Bu "sıkıştırmayı" çalıştırarak mongod --repairveya doğrudan bağlanıp çalıştırarak yapabilirsiniz db.repairDatabase().

Her iki durumda da dosyaları kopyalamak için bir yere ihtiyacınız vardır. Şimdi bir sıkıştırma yapmak için neden yeterli alanınız olduğunu bilmiyorum, ancak daha fazla alana sahip başka bir bilgisayarınız varsa bazı seçenekleriniz var.

  1. Veritabanını Mongo yüklü (kullanarak mongoexport) başka bir bilgisayara verin ve sonra aynı veritabanını (kullanarak mongoimport) içe aktarabilirsiniz . Bu daha sıkıştırılmış yeni bir veritabanı ile sonuçlanacaktır. Artık orijinal mongodveritabanını yeni veritabanı dosyalarıyla durdurabilirsiniz .
  2. Geçerli mongodu durdurun ve veritabanı dosyalarını daha büyük bir bilgisayara kopyalayın ve bu bilgisayarda onarımı çalıştırın. Daha sonra yeni veritabanı dosyalarını özgün bilgisayara geri taşıyabilirsiniz.

Şu anda Mongo'yu kullanarak "yerine oturmak" için iyi bir yol yoktur. Ve Mongo kesinlikle çok yer kaplayabilir.

Sıkıştırma için şu anda en iyi strateji Master-Slave kurulumunu çalıştırmaktır. Daha sonra Slave'i sıkıştırabilir, yakalamasına ve değiştirmesine izin verebilirsiniz. Hala biraz kıllı biliyorum. Belki Moğol ekibi yerinde daha iyi sıkıştırma yapabilir, ancak listelerinde yüksek olduğunu düşünmüyorum. Sürücü alanının şu anda ucuz olduğu varsayılmaktadır (ve genellikle).


Cevabınız için Gates Başkan Yardımcısı'na teşekkür ederiz. Bahsettiğiniz iki seçeneği düşünüyordum. Ancak böyle şeyler yapmadan önce, kompakt bir yerinde çözümün mevcut olup olmadığını bilmek istedim. Tekrar teşekkürler.
Meuble

3
Bugün itibariyle (2010-11-18) Dwight (Washington, DC'deki MongoDC etkinliğinde konuşan), veritabanınızı çevrimdışına almadan sıkıştırmak istiyorsanız çoğaltma / --repair / geçiş yaklaşımını önerdi.
David J.

10
Sadece bir kafa 'benim yaptığım gibi yapma' ve kök olarak onarım. db dosyalarını kök haline getirir. doh.
Totoro

18
'Kompakt' belgelerinde: "Bu işlem, dosya sisteminde kullanılan disk alanı miktarını azaltmaz." Bunun orijinal soruya nasıl bir çözüm olduğunu anlamıyorum.
Ed Norris

Orijinal soruya bakarsanız, sorunun bir kısmı onarım yapmak için çok fazla veriye sahip olmayı içeriyordu. Sürücünüzün 2 / 3'ünü bir DB ile doldurduysanız, onarım yapamazsınız. Yeni tahsis edilen dosyalar, yeni DB tamamen "kopyalanıp onarılmadan" ve "anahtar" hiçbir zaman gerçekleşmeden önce kalan alanı emer. İle compact, en azından mevcut dosyaları yerinde tutabilir. Katılıyorum, tam bir çözüm değil, ama artımlı bir gelişme.
Gates VP

39

Aynı sorunu yaşadım ve bunu komut satırında yaparak çözdüm:

mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename

iddia: 15936 Koleksiyon oluşturma db.collection başarısız oldu. Errmsg: istisna: boyutu belirtin: <n> sınırlı gerçek olduğunda
tweak2

: Bir ubuntu regresyonuna benziyor ... döküm dosyasında meta verilerin başlığı var: "tanımsız" ... bu silindiğinde içe aktarma sorunu giderilir.
tweak2

2
Veritabanım neredeyse tüm diski attı. 120 GB'dı (disk 160 GB) Kompakt dosya boyutunu küçültmez ve alan yetersizliği nedeniyle veritabanı yapılamaz. Mongodump & dropDatabase & mongorestore'dan sonra 40 GB veritabanı boyutuna sahibim.
Igor Benikov

Geri yükleme komutuna küçük düzeltmemongorestore --db databasename dump/databasename
JERRY

34

Görünüşe göre Mongo v1.9 + 'ın yerinde kompakt desteği var!

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

Buradaki dokümanlara bakın: http://docs.mongodb.org/manual/reference/command/compact/

"RepairDatabase'den farklı olarak, compact komutu işini yapmak için çift disk alanı gerektirmez. Çalışırken az miktarda ek alan gerektirir. Ayrıca, compact daha hızlıdır."


3
@AnujGupta "repairDatabase komutu veritabanındaki tüm koleksiyonları sıkıştırır. Her komutta ayrı ayrı kompakt komutu çalıştırmak aynıdır." docs.mongodb.org/manual/reference/command/repairDatabase/… . Bu nedenle, repairDatabase boyutu küçültülür. Koleksiyonlarımı her hafta birçok silme ve güncelleme ile sıkıştırıyorum. Kompakt repariDatabase daha çok seviyorum çünkü önce tüm veritabanı istediğiniz koleksiyonları hedeflenmiştir. İkincisi, sadece db dosya boyutunun x2 yerine (benim durumumda 500GB) 2GB boş alana ihtiyaç duyar.
Maziyar

1
Btw şunu kontrol et: "MongoDB, verilerinizi sıkıştırmak ve optimum performansı geri yüklemek için 2 farklı yol sunar: repairDatabase ve compact. Veritabanlarınız nispeten küçükse veya oldukça uzun bir süre rotasyondan bir düğüm almayı göze alabiliyorsanız RepairDatabase uygundur Veritabanı boyutlarımız ve sorgu iş yükümüz için tüm koleksiyonlarımızda sürekli sıkıştırma yapmak daha mantıklı. " blog.parse.com/2013/03/26/always-be-compcomptingting github.com/ParsePlatform/Ops/blob/master/tools/mongo_compact.rb
Maziyar

3
@Maziyar docs.mongodb.org/manual/reference/command/compact/#disk-space - "repairDatabase'den farklı olarak, compact dosya sisteminde boşluk bırakmaz".
Anuj Gupta

4
@Maziyar OP , elde edilen kullanılmayan alanı boşaltmak istiyor repairDatabase, değil compact. compactalan boşaltmaz, sadece kullanılan alanı birleştirir, bu da onu azaltmaz.
Anuj Gupta

5
Mongo'da 3.0 itibariyle compact edecek WiredTiger depolama motorunu kullanarak eğer alanını geri.
Gary

19

Mevcut veritabanındaki tüm koleksiyonları sıkıştır

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

13

Tam onarım yapmanız gerekirse repairpathseçeneği kullanın. Kullanılabilir alanı daha fazla olan bir diske doğrultun.

Örneğin, Mac bilgisayarımda şunları kullandım:

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

Güncelleme: MongoDB Çekirdek Sunucu Bileti 4266 başına , --nojournalbir hatayı önlemek için eklemeniz gerekebilir :

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

1
Bu harika çalıştı. Yerinde onarım için gereken 2x boşluğa sahip olmadığım için bir NAS monte ettim. Tek sorun, tamamlanması 18 saat sürdü, ancak işe yaradı. --Nojoural bayrağını eklediğinizden emin olun.
zenocon


7

StorageEngine'e dayanarak 2 yolu çözmemiz gerekiyor.

1. MMAP () motoru:

komut: db.repairDatabase ()

NOT: repairDatabase, geçerli veri kümenizin boyutuna ve 2 gigabayta eşit boş disk alanı gerektirir. Dbpath'ı tutan birimde yeterli alan yoksa, ayrı bir birim bağlayabilir ve bunu onarım için kullanabilirsiniz. RepairDatabase için ayrı bir birim bağlarken, repairDatabase'i komut satırından çalıştırmalı ve geçici onarım dosyalarının saklanacağı klasörü belirtmek için --repairpath anahtarını kullanmalısınız. örneğin: DB boyutunun 120 GB olduğunu hayal edin, (120 * 2) +2 = 242 GB Sabit Disk alanı gerekir.

koleksiyonu akıllıca yapmanın başka bir yolu, komut: db.runCommand ({compact: 'collectionName'})

2. WiredTiger: Kendi kendini otomatik olarak çözdü.


6

MongoDB'de alan ıslahı konusunda bazı karışıklıklar olmuştur ve bazı önerilen uygulamaların bazı dağıtım türlerinde yapılması tehlikelidir. Aşağıda daha fazla ayrıntı:

TL; DR repairDatabase , bir disk bozulmasından kurtarmaya çalışan bağımsız bir MongoDB dağıtımlarından veri kurtarmaya çalışır. Alanı kurtarırsa, tamamen bir yan etkidir . Mekanı kurtarmak asla koşmanın öncelikli konusu olmamalıdır repairDatabase.

Bağımsız bir düğümdeki alanı kurtarın

WiredTiger: WiredTiger ile bağımsız bir düğüm için, koşu compactOS'ye tek bir uyarı ile compactyer açacaktır: MongoDB 3.0.x üzerindeki WiredTiger üzerindeki komut şu hatadan etkilenmiştir: MongoDB 3.2.3'te düzeltilen SERVER-21833 . Bu sürümden önce compact, WiredTiger'de sessizce başarısız olabilirdi.

MMAPv1: MMAPv1'in çalışma şekli nedeniyle, MMAPv1 depolama motorunu kullanarak alanı kurtarmak için güvenli ve desteklenen bir yöntem yoktur. compactMMAPv1'de veri dosyaları birleştirilir, bu da yeni belgeler için daha fazla alan sağlar, ancak işletim sistemine geri alan bırakmaz.

Sen olabilir çalıştıramaz repairDatabasetam bu sonuçlarını anlamak durumunda potansiyel olarak tehlikeli , çünkü komuta (aşağıya bakınız) repairDatabaseesasen bozuk belgeleri atarak tüm veritabanını yeniden yazar. Bir yan etki olarak, üzerinde herhangi bir parçalanma olmadan yeni MMAPv1 veri dosyaları oluşturacak ve OS'ye geri alan bırakacaktır.

Daha az maceracı yöntemi için, çalışan mongodumpve mongorestoredağıtımın boyutuna dair bir MMAPv1 dağıtım, konu hem mümkün olabilir.

Çoğaltma kümesinde alan kurtarma

Çoğaltma kümesi yapılandırmaları için, alanı kurtarmanın en iyi ve en güvenli yöntemi , hem WiredTiger hem de MMAPv1 için bir ilk eşitleme yapmaktır.

Kümedeki tüm düğümlerden alan kurtarmanız gerekirse, yuvarlanan bir ilk senkronizasyon gerçekleştirebilirsiniz. Yani, birincil olarak her ikincisinde ilk senkronizasyonu gerçekleştirin ve sonunda birincil senkronizasyonu gerçekleştirin. İlk senkronizasyon yönteminin yuvarlanması, çoğaltma kümesi bakımını gerçekleştirmek için en güvenli yöntemdir ve ayrıca bonus olarak kesinti süresi içermez.

Hareketli bir ilk senkronizasyon gerçekleştirmenin uygulanabilirliğinin dağıtımınızın boyutuna da bağlı olduğunu lütfen unutmayın. Aşırı büyük dağıtımlar için, ilk senkronizasyonu yapmak mümkün olmayabilir ve bu nedenle seçenekleriniz biraz daha sınırlıdır. WiredTiger kullanılırsa, sen olabilir , setin bir ikincil out almak işletilen bağımsız olarak başlatmak mümkün compactüzerinde ve sete bunu yeniden katılmak.

ilişkin repairDatabase

Lütfen repairDatabaseçoğaltma kümesi düğümlerinde çalıştırmayın . Bu, repairDatabase sayfasında belirtildiği ve aşağıda daha ayrıntılı olarak açıklandığı gibi çok tehlikelidir .

repairDatabaseKomut hiçbir şeyi onarmaya çalışmadığından, ad biraz yanıltıcı. Komut, bağımsız bir düğümde bozuk belgelere yol açabilecek disk bozulması olduğunda kullanılmak üzere tasarlanmıştır .

repairDatabaseKomut daha doğru "kurtarma veritabanı" olarak tarif edilebilir. Yani, veritabanını başlatabileceğiniz ve ondan bozulmamış bir belgeyi kurtarabileceğiniz bir duruma getirmek için bozuk belgeleri atarak veritabanlarını yeniden oluşturur.

MMAPv1 dağıtımlarında, veritabanı dosyalarının bu yeniden oluşturulması bir yan etki olarak işletim sistemine alan açar . İşletim sistemine yer bırakmak asla bir amaç değildi.

Sonuçları repairDatabasebir yineleme kümesinin üzerinde

Bir çoğaltma kümesinde, MongoDB kümedeki tüm düğümlerin aynı verileri içermesini bekler. repairDatabaseBir çoğaltma kümesi düğümünde çalışırsanız , düğümün algılanmamış bozulma içermesi repairDatabaseve bozuk belgeleri sizin yerinize kaldırması ihtimali vardır .

Tahmin edilebileceği gibi, bu, düğümün kümenin geri kalanından farklı bir veri kümesi içermesini sağlar. Bir güncelleme bu tek dokümana çarparsa, tüm set çökebilir.

Daha da kötüsü, bu durumun uzun süre uykuda kalabilmesi, sadece belirgin bir neden olmadan aniden saldırılması tamamen mümkündür.


5

Bir koleksiyondan büyük miktarda veri silinmesi ve koleksiyonun yeni belgeler için asla silinen alanı kullanmaması durumunda, bu alanın diğer veritabanları veya koleksiyonlar tarafından kullanılabilmesi için işletim sistemine geri döndürülmesi gerekir. Disk alanını birleştirmek ve kullanılabilir boş alanı yeniden kazanmak için bir kompakt veya onarım işlemi çalıştırmanız gerekecektir.

Sıkıştırma işleminin davranışı aşağıdaki gibi MongoDB motoruna bağlıdır

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

MMAPv1

Sıkıştırma işlemi veri dosyalarını ve dizinleri birleştirir. Ancak, işletim sistemine yer açmaz. Operasyon, MongoDB tarafından yeniden kullanım için birleştirmek ve daha bitişik alan oluşturmak için hala yararlıdır. Ancak, boş disk alanı çok düşük olduğunda hiçbir işe yaramaz.

Sıkıştırma işlemi sırasında 2 GB'a kadar ek disk alanı gerekir.

Sıkıştırma işlemi sırasında bir veritabanı düzeyi kilidi tutulur.

WiredTiger

WiredTiger motoru varsayılan olarak MMAPv1'den daha az disk alanı tüketen sıkıştırma sağlar.

Kompakt işlem, işletim sistemine boş alan bırakır. Kompakt işlemi çalıştırmak için minimum disk alanı gerekir. WiredTiger, veritabanı düzeyinde kilide ihtiyaç duyduğu için veritabanındaki tüm işlemleri de engeller.

İçin MMAPv1 motor, kompakt Doest işletim sistemine yer döndürmez. Kullanılmayan alanı serbest bırakmak için onarım işlemini çalıştırmanız gerekir.

db.runCommand({repairDatabase: 1})

3

Mongodb 3.0 ve üstü, yeni bir depolama motoruna sahiptir - WiredTiger. Benim durumumda anahtarlama motoru, disk kullanımını 100 Gb'den 25Gb'ye düşürdü.


1

Veritabanı dosyalarının boyutu küçültülemez. Veritabanını "onarırken", yalnızca mongo sunucusunun dosyalarından bazılarını silmesi mümkündür. Büyük miktarda veri silinmişse, mongo sunucusu onarım sırasında mevcut dosyalarından bazılarını "serbest bırakır" (siler).


1

Genel olarak compact repairDatabase için tercih edilir. Ancak, onarımın kompakttan daha büyük bir avantajı, tüm kümeye onarım yapabilmenizdir. Kompakt her parçaya giriş yapmanız gerekir, bu da can sıkıcı bir durumdur.


1

Aynı sorunu yaşadığımda, mongo sunucumu durdurdum ve komutla tekrar başlattım

mongod --repair

Onarım işlemini çalıştırmadan önce HDD'nizde yeterli boş alan olup olmadığını kontrol etmelisiniz (min - veritabanınızın boyutu)


1

Bağımsız mod için kompakt veya onarım kullanabilirsiniz,

Kırık küme veya çoğaltma kümesi için, benim deneyimime göre, birincil üzerinde kompakt çalıştırdıktan sonra ikincil sıkıştırmayı izledikten sonra, birincil veritabanının boyutu azaltıldı, ancak ikincil değil. İkincil veritabanının boyutunu azaltmak için yeniden senkronize etmek isteyebilirsiniz . ve bunu yaparak ikincil veritabanı boyutunun birincil boyuttan daha da küçük olduğunu görebilirsiniz, sanırım kompakt komut koleksiyonu gerçekten sıkıştırmıyor. Böylece, çoğaltma kümesinin birincil ve ikincil anahtarlama ve tekrar resync üye yapıyor sona erdi .

Sonuç olarak, parçalanmış / çoğaltma kümesinin boyutunu azaltmanın en iyi yolu, yeniden eşitleme üyesi yapmak, birincil ikincil anahtarı değiştirmek ve yeniden eşitleme yapmaktır.


0

parçalanmış küme durumunda mongoDB onarımı önerilmez.

Çoğaltma kümesi gölgeli kümeyi kullanıyorsanız, compact komutunu kullanın, tüm koleksiyonların tüm verilerini ve dizin dosyalarını yeniden yazar ve birleştirir. sözdizimi:

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

zorla kullanıldığında: gerçek, kompakt çoğaltma kümesinin ilkinde çalışır. Örneğin db.runCommand ( { command : "collection_name", force : true } )

Dikkate alınması gereken diğer hususlar: -Bu işlemleri engeller. bakım penceresinde yürütülmesi tavsiye edilir. -Farklı sunucularda çalışan çoğaltma kümeleri varsa, her üyede ayrı ayrı yürütülmesi gerekir - Kırık küme durumunda, kompaktın her kırık üyesinde ayrı ayrı yürütülmesi gerekir. Mongos örneğine karşı çalıştırılamıyor.


-5

Bunu yapabilmemin sadece bir yolu. Mevcut verilerinizin güvenliği konusunda garanti verilmez. Kendi riskinizle deneyin.

Veri dosyalarını doğrudan silin ve mongod'u yeniden başlatın.

Örneğin, ubuntu (varsayılan veri yolu: / var / lib / mongodb) ile, şu şekilde adlandırılmış birkaç dosya vardı: koleksiyon. #. Koleksiyonu saklıyorum. 0 ve diğerlerini sildim.

Veritabanında ciddi verileriniz yoksa daha kolay bir yol gibi görünüyor.


dosyalar <veritabanı_adı> olarak depolanır. <sayı> örn. mydb.3 - koleksiyona söyleyemezsiniz.
bobmarksie
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.