Уменьшение размера файла базы данных MongoDB

165

У меня есть база данных MongoDB, которая когда-то была большой (> 3 ГБ). С тех пор документы были удалены, и я ожидал, что размер файлов базы данных уменьшится соответственно.

Но поскольку MongoDB сохраняет выделенное пространство, файлы все еще остаются большими.

Здесь и там я читал, что команда администратора mongod --repairиспользуется для освобождения неиспользуемого пространства, но на диске недостаточно места для выполнения этой команды.

Вы знаете, как я могу освободить неиспользуемое пространство?

Meuble
источник
7
Этот вопрос считается ответом? Нужно ли нам больше данных?
Гейтс VP
2
начиная с версии 2.8, вы можете сжимать ваши данные , что значительно экономит место.
Сальвадор Дали
1
У меня была та же самая проблема, самый простой способ решить ее - сделать копию базы данных с помощью функции copyDatabase (), затем db.dropDatabase () исходную базу данных и затем скопировать базу данных обратно на место. моя база данных была в основном пуста, и когда я делал копию, копировались только реальные используемые данные. удаление оригинальной базы данных удалило большие файлы. использование db.repairDatabase () не было опцией, так как мой сервер уже занимал мало места на диске, и для этой операции потребовалось бы очень много свободного места, намного больше, чем необходимо для этой операции.
user3892260

Ответы:

144

ОБНОВЛЕНИЕ: с помощью compactкоманды и WiredTiger похоже, что дополнительное пространство на диске будет фактически освобождено для ОС .


ОБНОВЛЕНИЕ: с v1.9 + есть compactкоманда.

Эта команда выполнит сжатие "in-line". Это все еще потребует некоторого дополнительного пространства, но не так много.


MongoDB сжимает файлы:

  • копирование файлов в новое место
  • перебирая документы и переупорядочивая их
  • замена исходных файлов новыми файлами

Вы можете сделать это «сжатие», запустив mongod --repairили подключившись напрямую и запустив db.repairDatabase().

В любом случае вам нужно где-то место для копирования файлов. Теперь я не знаю, почему у вас недостаточно места для выполнения сжатия, однако у вас есть несколько вариантов, если у вас есть другой компьютер с большим количеством места.

  1. Экспортируйте базу данных на другой компьютер с установленным Mongo (используя mongoexport), а затем вы можете импортировать эту же базу данных (используя mongoimport). Это приведет к новой базе данных, которая будет более сжатой. Теперь вы можете остановить оригинальную mongodзамену новыми файлами базы данных, и все готово.
  2. Остановите текущий mongod и скопируйте файлы базы данных на больший компьютер и запустите восстановление на этом компьютере. Затем вы можете переместить новые файлы базы данных обратно на исходный компьютер.

В настоящее время не существует хорошего способа «компактирования на месте» с использованием Mongo. И Монго определенно может высосать много места.

Лучшая стратегия для уплотнения - запустить установку Master-Slave. Затем вы можете сжать Ведомого, позволить ему догнать и переключить их. Я знаю еще немного волосатым. Может быть, команда Монго придумает лучшее уплотнение на месте, но я не думаю, что это занимает первое место в их списке. Дисковое пространство в настоящее время считается дешевым (и обычно это так).

Гейтс В.П.
источник
Спасибо Гейтс В.П. за ваш ответ. Я думал о двух вариантах, которые вы упомянули. Но прежде чем делать такие вещи, я хотел узнать, было ли доступно компактное решение на месте. Еще раз спасибо.
Meuble
3
На сегодняшний день (2010-11-18) Дуайт (выступая на мероприятии MongoDC в Вашингтоне, округ Колумбия) рекомендовал подход репликации / --repair / switch, если вы хотите сжать, не переводя базу данных в автономный режим.
Дэвид Дж.
10
Просто хедз-ап "не делай как я" и запусти --repair от имени root. преобразует файлы базы данных в корень. DOH.
Тоторо
18
Документация для «compact» гласит: «Эта операция не уменьшит объем дискового пространства, используемого в файловой системе». Я не понимаю, как это решение исходного вопроса.
Эд Норрис
Если вы посмотрите на исходный вопрос, часть проблемы связана с наличием слишком большого количества данных для выполнения ремонта. Если вы заполнили 2/3 диска одной БД, вы не сможете выполнить ремонт. Вновь выделенные файлы будут занимать оставшееся пространство до того, как новая БД будет полностью «скопирована и восстановлена», и «переключения» никогда не произойдет. С помощью compactон может по крайней мере сохранить существующие файлы на месте. Я согласен, это не полное решение, но это постепенное улучшение.
Гейтс VP
39

У меня была та же проблема, и я решил ее, просто выполнив это в командной строке:

mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename
user435943
источник
утверждение: 15936 Создание коллекции db.collection не удалось. Errmsg: исключение: указать размер: <n>, если значение capped равно true
tweak2
: Похоже на регрессию в Ubuntu ... в файле дампа есть метаданные с ограничением: "undefined" ... удаление этих исправляет проблему импорта.
tweak2
2
Моя база данных забила почти весь диск. это было 120 ГБ (диск 160 ГБ). Компакт не уменьшает размер файла, и восстановление базы данных невозможно из-за недостатка места. После mongodump & dropDatabase & mongorestore of db у меня есть 40 ГБ размера базы данных.
Игорь Беников
Небольшая поправка к команде восстановленияmongorestore --db databasename dump/databasename
JERRY
34

Похоже, Mongo v1.9 + имеет поддержку компакта на месте!

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

Смотрите документы здесь: http://docs.mongodb.org/manual/reference/command/compact/

«В отличие от repairDatabase, команда compact не требует двойного дискового пространства для своей работы. Она требует небольшого дополнительного пространства во время работы. Кроме того, compact работает быстрее».

awaage
источник
3
@AnujGupta "Команда repairDatabase уплотняет все коллекции в базе данных. Она идентична выполнению команды сжатия для каждой коллекции в отдельности." docs.mongodb.org/manual/reference/command/repairDatabase/… . Так что, если repairDatabase уменьшает размер так компактно. Я сжимал свои коллекции с большим количеством удаления и обновления каждую неделю. Мне нравится compact больше, чем repariDatabase, потому что сначала он нацелен на коллекции, которые вы хотите, а не на всю базу данных. Во-вторых, ему просто нужно 2 ГБ свободного места вместо х2 вашего размера файла в БД (в моем случае 500 ГБ).
Мазияр
1
Кстати, проверьте это: «MongoDB предоставляет 2 различных способа уплотнения ваших данных и восстановления оптимальной производительности: repairDatabase и compact. RepairDatabase подходит, если ваши базы данных относительно малы, или вы можете позволить себе вывести узел из ротации в течение довольно длительного времени. . Для размеров нашей базы данных и рабочей нагрузки запросов было более целесообразно проводить непрерывное сжатие для всех наших коллекций ». blog.parse.com/2013/03/26/always-be-compacting github.com/ParsePlatform/Ops/blob/master/tools/mongo_compact.rb
Мазияр,
3
@Maziyar docs.mongodb.org/manual/reference/command/compact/#disk-space - «В отличие от repairDatabase, compact не освобождает место в файловой системе».
Анудж Гупта
4
@Maziyar OP хочет освободить неиспользуемое пространство , что достигается за счет repairDatabase, а не compact. compactне освобождает пространство, оно только дефрагментирует использованное пространство, что не уменьшает его.
Анудж Гупта
5
По состоянию Монго 3.0, compact будет востребовать пространство при использовании механизма хранения WiredTiger.
Гари
19

Сжать все коллекции в текущей базе данных

db.getCollectionNames().forEach(function (collectionName) {
    print('Compacting: ' + collectionName);
    db.runCommand({ compact: collectionName });
});
OzzyCzech
источник
13

Если вам нужно выполнить полный ремонт, используйте repairpathопцию. Укажите это на диск с большим количеством свободного места.

Например, на моем Mac я использовал:

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

Обновление: согласно MongoDB Core Server Ticket 4266 , вам может потребоваться добавить, --nojournalчтобы избежать ошибки:

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal
Дэвид Дж.
источник
1
Это сработало отлично. Мне не хватило 2х места, необходимого для ремонта на месте, поэтому я установил NAS. Единственная проблема, это заняло 18 часов, но это сработало. Обязательно добавьте флаг --nojoural.
zenocon
11

Начиная с версии 2.8 Mongo, вы можете использовать сжатие . У вас будет 3 уровня сжатия с движком WiredTiger, mmap (который по умолчанию в 2.6 не обеспечивает сжатие):

Вот пример того, сколько места вы сможете сэкономить для 16 ГБ данных:

введите описание изображения здесь

данные взяты из этой статьи.

Сальвадор Дали
источник
7

Нам нужно решить 2 пути, основанные на StorageEngine.

1. MMAP () двигатель:

команда: db.repairDatabase ()

ПРИМЕЧАНИЕ. Для восстановления базы данных требуется свободное место на диске, равное размеру текущего набора данных плюс 2 гигабайта. Если на томе, содержащем dbpath, недостаточно места, вы можете смонтировать отдельный том и использовать его для восстановления. При монтировании отдельного тома для repairDatabase вы должны запустить repairDatabase из командной строки и использовать ключ --repairpath, чтобы указать папку, в которой будут храниться временные файлы восстановления. Например: представьте, что размер БД составляет 120 ГБ, значит, (120 * 2) +2 = 242 ГБ требуется место на жестком диске.

Другой способ сделать коллекцию - команда: db.runCommand ({compact: 'collectionName'})

2. WiredTiger: автоматически разрешается самостоятельно.

Картиккумар Нагарадж
источник
6

В MongoDB произошла значительная путаница по поводу освоения космоса, и некоторые рекомендуемые практики совершенно опасны для использования в определенных типах развертывания. Более подробная информация ниже:

TL; DR repairDatabase пытается спасти данные из автономных развертываний MongoDB, которые пытаются восстановиться после повреждения диска. Если он восстанавливает пространство, это чисто побочный эффект . Восстановление пространства никогда не должно быть главным соображением бега repairDatabase.

Восстановить пространство в автономном узле

WiredTiger: для автономного узла с WiredTiger при запуске compactосвободится пространство для ОС с одним предупреждением: на compactкоманду на WiredTiger в MongoDB 3.0.x повлияла эта ошибка: SERVER-21833, которая была исправлена ​​в MongoDB 3.2.3. До этой версии compactна WiredTiger мог молча провалиться.

MMAPv1: из-за того, как работает MMAPv1, нет безопасного и поддерживаемого метода для восстановления пространства с использованием механизма хранения MMAPv1. compactв MMAPv1 будет выполнять дефрагментацию файлов данных, потенциально освобождая место для новых документов, но не освобождая пространство обратно в ОС.

Вы можете запустить, repairDatabaseесли полностью понимаете последствия этой потенциально опасной команды (см. Ниже), поскольку по repairDatabaseсуществу перезаписывает всю базу данных, отбрасывая поврежденные документы. Как побочный эффект, это создаст новые файлы данных MMAPv1 без какой-либо фрагментации и освободит место для ОС.

Для менее авантюрного метода он может быть запущен mongodumpи mongorestoreвозможен также в развертывании MMAPv1, в зависимости от размера вашего развертывания.

Восстановить пространство в наборе реплик

Для конфигураций набора реплик лучший и самый безопасный способ восстановления пространства - выполнить первоначальную синхронизацию как для WiredTiger, так и для MMAPv1.

Если вам нужно восстановить пространство со всех узлов в наборе, вы можете выполнить скользящую начальную синхронизацию. То есть, выполнить начальную синхронизацию на каждом из вторичных серверов, прежде чем окончательно отключить первичный, и выполнить на нем начальную синхронизацию. Скользящий метод начальной синхронизации - самый безопасный метод для выполнения обслуживания набора реплик, и он также не включает простоев в качестве бонуса.

Обратите внимание, что возможность выполнения скользящей начальной синхронизации также зависит от размера вашего развертывания. Для чрезвычайно больших развертываний может оказаться невозможным выполнить первоначальную синхронизацию, и, следовательно, ваши параметры несколько более ограничены. Если используется WiredTiger, вы можете выбрать один дополнительный из набора, запустить его как автономный, запустить compactна нем и присоединиться к нему.

относительно repairDatabase

Пожалуйста, не запускайте repairDatabaseна узлах набора реплик . Это очень опасно, как упомянуто на странице repairDatabase и описано более подробно ниже.

Название repairDatabaseнемного вводит в заблуждение, так как команда не пытается что-либо исправить. Эта команда предназначалась для использования в случае повреждения диска на отдельном узле , что может привести к повреждению документов.

Команда repairDatabaseможет быть более точно описана как «база данных по утилизации». Таким образом, он воссоздает базы данных, отбрасывая поврежденные документы, пытаясь привести базу данных в состояние, в котором вы можете ее запустить, и извлечь из нее неповрежденный документ.

В развертываниях MMAPv1 такая перестройка файлов базы данных освобождает пространство для ОС как побочный эффект . Освобождение места для ОС никогда не было целью.

Последствия repairDatabaseна реплику набора

В наборе реплик MongoDB ожидает, что все узлы в наборе будут содержать идентичные данные. Если вы работаете repairDatabaseна узле набора реплик, есть вероятность, что узел содержит необнаруженное повреждение и repairDatabaseпокорно удалит поврежденные документы за вас.

Как и ожидалось, это заставляет этот узел содержать набор данных, отличный от остальной части набора. Если обновление попадает в этот единственный документ, весь набор может потерпеть крах.

Что еще хуже, вполне возможно, что эта ситуация может оставаться в состоянии покоя в течение длительного времени, только чтобы нанести удар внезапно без видимой причины.

kevinadi
источник
5

В случае, если большая часть данных удаляется из коллекции, и коллекция никогда не использует удаленное пространство для новых документов, это пространство необходимо вернуть операционной системе, чтобы его могли использовать другие базы данных или коллекции. Вам нужно будет выполнить операцию сжатия или восстановления, чтобы дефрагментировать дисковое пространство и восстановить доступное свободное пространство.

Поведение процесса уплотнения зависит от механизма MongoDB следующим образом

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

MMAPv1

Операция сжатия дефрагментирует файлы данных и индексы. Тем не менее, он не освобождает место для операционной системы. Операция по-прежнему полезна для дефрагментации и создания более непрерывного пространства для повторного использования MongoDB. Однако это бесполезно, когда свободное место на диске очень мало.

Во время операции уплотнения требуется дополнительное дисковое пространство до 2 ГБ.

Блокировка уровня базы данных удерживается во время операции сжатия.

WiredTiger

Движок WiredTiger по умолчанию обеспечивает сжатие, которое потребляет меньше дискового пространства, чем MMAPv1.

Компактный процесс освобождает свободное место для операционной системы. Для выполнения компактной операции требуется минимальное дисковое пространство. WiredTiger также блокирует все операции с базой данных, так как требует блокировки на уровне базы данных.

Для двигателя MMAPv1 компактный Doest не возвращает место операционной системе. Вам необходимо выполнить операцию восстановления, чтобы освободить неиспользуемое пространство.

db.runCommand({repairDatabase: 1})
ВИШАЛ КУМАВАТ
источник
3

Mongodb 3.0 и выше имеет новый механизм хранения - WiredTiger. В моем случае коммутатор уменьшил использование диска со 100 Гб до 25 Гб.

Хетт
источник
1

Файлы базы данных не могут быть уменьшены в размере. При восстановлении базы данных сервер Монго может удалить только некоторые из его файлов. Если большой объем данных был удален, сервер mongo «освободит» (удалит) во время восстановления некоторые из существующих файлов.

ivankoni
источник
1

В целом компакт предпочтительнее, чем repairDatabase. Но одним из преимуществ восстановления по сравнению с компактным является возможность восстановления всего кластера. Компактный, вы должны войти в каждый осколок, что немного раздражает.

user2077221
источник
1

Когда у меня возникла та же проблема, я остановил свой сервер Монго и снова запустил его командой

mongod --repair

Перед выполнением операции восстановления следует проверить, достаточно ли у вас свободного места на жестком диске (min - размер вашей базы данных).

Александр Макаров
источник
1

Для автономного режима вы можете использовать компакт или ремонт,

Для моего сегментированного кластера или набора реплик, по моему опыту, после того, как вы запустили сжатие на первичной, а затем на компактной вторичной, размер первичной базы данных уменьшился, но не вторичной. Возможно, вы захотите выполнить повторную синхронизацию, чтобы уменьшить размер вторичной базы данных. и, делая это, вы можете обнаружить, что размер вторичной базы данных даже больше, чем первичной, я думаю, что команда compact на самом деле не сжимает коллекцию. Итак, я закончил тем, что переключил основной и дополнительный набор реплик и выполнил повторную синхронизацию снова .

Мой вывод заключается в том, что лучший способ уменьшить размер набора sharded / replica - выполнить повторную синхронизацию, переключение первичного вторичного и повторную синхронизацию.

WiSM
источник
0

mongoDB - ремонт не рекомендуется в случае сегментированного кластера.

Если вы используете кластерный набор репликации, используйте компактную команду, она перезаписывает и дефрагментирует все файлы данных и индексов всех коллекций. синтаксис:

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

при использовании с силой: true, компактный запуск на первичном из набора реплик. например db.runCommand ( { command : "collection_name", force : true } )

Другие моменты для рассмотрения: - Он блокирует операции. поэтому рекомендуется выполнить в окне обслуживания. -Если наборы реплик, запущенные на разных серверах, должны выполняться на каждом элементе отдельно - В случае сегментированного кластера, сжатие должно выполняться на каждом элементе сегмента отдельно. Невозможно выполнить против экземпляра Mongos.

SaP
источник
-5

Только один способ, которым я смог это сделать. Нет гарантии безопасности ваших существующих данных. Попробуйте на свой страх и риск.

Удалите файлы данных напрямую и перезапустите mongod.

Например, в Ubuntu (путь по умолчанию к данным: / var / lib / mongodb) у меня было несколько файлов с именем вроде: collection. #. Я держу коллекцию.0 и удалил все остальные.

Кажется, проще, если у вас нет серьезных данных в базе данных.

frnkxiao
источник
файлы хранятся как <имя_базы_данных>. <номер>, например, mydb.3 - вы не можете сказать коллекцию.
bobmarksie