Восстановление реплики MongoDB из директории БД
Введение
Логика восстановления следующая:
01 - Помещаем спасённую папку БД в отдельное место;
02 - Запускаем в этом месте простой процесс mongod указывающий на спасённую папку;
03 - Подключаем к этому процессу клиент mongo;
04 - Смотрим, что там всё есть (есть необходимые базы, в них есть нужные таблицы с нужным содержимым);
05 - И если всё ок, удаляем от туда информацию о связанности с бывшим кластером (несколько команд);
06 - Корректно останавливаем mongod;
07 - Полученную директорию помещаем на место первой реплики шарда;
08 - Запускаем первую реплику шарда;
09 - Инициируем её;
10 - Запускаем другие реплики с пустыми БД;
11 - Подсоединяем их к первой;
12 - Наблюдаем процесс репликации данных из первой реплики в остальные;
13 - подключаем шард к кластеру в mongos кластера.
Подготовка спасённой папки
Пусть спасённая папка называется mongo-data-1-0 - и пусть она раньше была подсоединена к шарду с именем rs1 .
01 - Кладём её в текущую папку и запускаем команду
docker run --name=asd --rm -it -v $PWD/mongo-data-1-0:/data/db mongo:4.2.0 mongod --dbpath /data/db
Должны появиться логи запущенного сервера.
*Примечание: asd - замените на другое имя, если это уже где-то используется и далее вместо asd используется то, которое вы исользовали здесь
02 - Подключаемся к этому серверу из другой консоли:
02.1 - Ищем докер-контэйнер командой
docker ps | grep asd
02.2 - Теперь заходим в контейнер:
docker exec -it ИД_КОНТЭЙНЕРА mongo
Должно появиться приглашение от mongo.
03 - Смотрим содержимое директории и удостоверяемся что там всё есть - полезные команды для этого:
show databases;
use ИМЯ_БД
show tables
db.ИМЯ_ТАБЛИЦЫ.count()
04.1 - Теперь удаляем БД local командами
use local
db.dropDatabase()
Должно появиться сообщение об удачном удалении:
{ "dropped" : "local", "ok" : 1 }
04.2 - Теперь заходим в БД admin командой:
use admin
04.3 - И смотрим содержимое таблицы system.version командой:
db.system.version.find({})
Если появился документ с идентификатором "_id" : "shardIdentity", то его надо удалить. Если такого документа нет, то пропускаем следующий шаг.
04.4 - Удалите shardIdentity командой:
db.system.version.remove({"_id":"shardIdentity"});
Должно появиться сообщение об успешном удалении:
WriteResult({ "nRemoved" : 1 })
05 - Теперь останавливаем сервер командой
use admin
db.shutdownServer()
Поднятие нового шарда
01 - Далее копируем подготовленную спасённую папку на место реплики шарда и запускаем только один сервер реплики - другие пока не запускаем.
Команды для запуска первой реплики должны быть примерно такими
mongod --replSet=rs1 --shardsvr --dbdata=/data/db
dbdata - можно не указывать. Здесь важен параметр replSet.
02 - Теперь надо подключиться к этой реплике
Например, можно использовать команду:
kubectl -n mybpm exec -it mongo-data-1-0-0 -- mongo
Ваша команда может быть другой.
Должно появиться приглашение от mongo c одним пустым знаком 'больше' - > . Это обозначает, что данная реплика не инициирована.
03 - Теперь надо инициировать реплику командой
var cfg = {
"_id": "rs1",
"protocolVersion": 1,
"members": [
{
"_id": 1,
"host": "mongo-data-1-0-0.mongo-data-1-0:27017"
}
]
};
rs.initiate(cfg, {force: true});
rs.reconfig(cfg, {force: true});
Теперь нужно выйти и зайти снова - эта реплика должна стать PRIMARY, что свидетельствует приглашение:
rs1:PRIMARY>
Далее запускаем другие пустые реплики
И подсоединяем их к этой реплики командами:
rs.add( { host: "mongo-data-1-1-0.mongo-data-1-1:27017", priority: 0, votes: 0 } )
rs.add( { host: "mongo-data-1-2-0.mongo-data-1-2:27017", priority: 0, votes: 0 } )
Посмотреть состояние шарда можно командой
rs.status()
Эта команда должна показать одну реплику в статусе PRIMARY а остальные в статусе SECONDARY. По началу некоторое время ранее пустые реплики могут быть в статусе STARTUP2 - это означает, что на них идёт копирование данных. При завершении копирования статус этой реплики смениться на SECONDARY.