010
Восстановление реплики MongoDB из директории
011 БД
012
013
Введение
014
015
Логика восстановления следующая:
016
017
01 - Помещаем спасённую папку БД в отдельное место;
018
019
02 - Запускаем в этом месте простой процесс mongod указывающий
020 на спасённую папку;
021
022
03 - Подключаем к этому процессу клиент mongo;
023
024
04 - Смотрим, что там всё есть (есть необходимые базы, в них
025 есть нужные таблицы с нужным содержимым);
026
027
05 - И если всё ок, удаляем от туда информацию о связанности с
028 бывшим кластером (несколько команд);
029
030
06 - Корректно останавливаем mongod;
031
032
07 - Полученную директорию помещаем на место первой реплики
033 шарда;
034
035
08 - Запускаем первую реплику шарда;
036
037
09 - Инициируем её;
038
039
10 - Запускаем другие реплики с пустыми БД;
040
041
11 - Подсоединяем их к первой;
042
043
12 - Наблюдаем процесс репликации данных из первой реплики в
044 остальные;
045
046
13 - подключаем шард к кластеру в mongos кластера.
047
048
Подготовка спасённой папки
049
050
Пусть спасённая папка называется mongo-data-1-0 - и пусть
051 она раньше была подсоединена к шарду с именем rs1 .
052
053
01 - Кладём её в текущую папку и запускаем команду
054
055
056 docker run --name=asd --rm -it -v $PWD/mongo-data-1-0:/data/db mongo:4.2.0 mongod --dbpath /data/db
057
058
059
060
061
062
Должны появиться логи запущенного сервера.
063
064
*Примечание: asd - замените на другое имя, если это уже где-то
065 используется и далее вместо asd используется то, которое вы
066 исользовали здесь
067
068
02 - Подключаемся к этому серверу из другой консоли:
069
070
02.1 - Ищем докер-контэйнер командой
071
072
073 docker ps | grep asd
074
075
076
077
078
079
02.2 - Теперь заходим в контейнер:
080
081
082 docker exec -it ИД_КОНТЭЙНЕРА mongo
083
084
085
086
087
088
Должно появиться приглашение от mongo.
089
090
03 - Смотрим содержимое директории и удостоверяемся что там всё
091 есть - полезные команды для этого:
092
093
094 show databases;
095 use ИМЯ_БД
096 show tables
097 db.ИМЯ_ТАБЛИЦЫ.count()
098
099
100
101
102
103
04.1 - Теперь удаляем БД local командами
104
105
106 use local
107 db.dropDatabase()
108
109
110
111
112
113
Должно появиться сообщение об удачном удалении:
114
115
116 { "dropped" : "local", "ok" : 1 }
117
118
119
120
121
122
04.2 - Теперь заходим в БД admin командой:
123
124
use admin
125
126
04.3 - И смотрим содержимое таблицы system.version командой:
127
128
129 db.system.version.find({})
130
131
132
133
134
135
Если появился документ с идентификатором "_id" :
136 "shardIdentity", то его надо удалить. Если такого документа нет, то
137 пропускаем следующий шаг.
138
139
04.4 - Удалите shardIdentity командой:
140
141
142 db.system.version.remove({"_id":"shardIdentity"});
143
144
145
146
147
148
Должно появиться сообщение об успешном удалении:
149
150
151 WriteResult({ "nRemoved" : 1 })
152
153
154
155
156
157
05 - Теперь останавливаем сервер командой
158
159
160 use admin
161 db.shutdownServer()
162
163
164
165
166
167
Поднятие нового шарда
168
169
01 - Далее копируем подготовленную спасённую папку на место
170 реплики шарда и запускаем только один сервер реплики - другие пока
171 не запускаем.
172
173
Команды для запуска первой реплики должны быть примерно
174 такими
175
176
177 mongod --replSet=rs1 --shardsvr --dbdata=/data/db
178
179
180
181
182
183
dbdata - можно не указывать. Здесь важен параметр replSet.
184
185
02 - Теперь надо подключиться к этой реплике
186
187
Например, можно использовать команду:
188
189
190 kubectl -n mybpm exec -it mongo-data-1-0-0 -- mongo
191
192
193
194
195
196
Ваша команда может быть другой.
197
198
Должно появиться приглашение от mongo c одним пустым знаком
199 'больше' - > . Это обозначает, что данная реплика не
200 инициирована.
201
202
03 - Теперь надо инициировать реплику командой
203
204
205 var cfg = {
206 "_id": "rs1",
207 "protocolVersion": 1,
208 "members": [
209 {
210 "_id": 1,
211 "host": "mongo-data-1-0-0.mongo-data-1-0:27017"
212 }
213 ]
214 };
215 rs.initiate(cfg, {force: true});
216 rs.reconfig(cfg, {force: true});
217
218
219
220
221
Теперь нужно выйти и зайти снова - эта реплика должна стать
222 PRIMARY, что свидетельствует приглашение:
223
224
225 rs1:PRIMARY>
226
227
228
229
230
231
Далее запускаем другие пустые реплики
232
233
И подсоединяем их к этой реплики командами:
234
235
236 rs.add( { host: "mongo-data-1-1-0.mongo-data-1-1:27017", priority: 0, votes: 0 } )
237
238 rs.add( { host: "mongo-data-1-2-0.mongo-data-1-2:27017", priority: 0, votes: 0 } )
239
240
241
242
243
244
Посмотреть состояние шарда можно командой
245
246
247 rs.status()
248
249
250
251
252
253
Эта команда должна показать одну реплику в статусе PRIMARY а
254 остальные в статусе SECONDARY. По началу некоторое время ранее
255 пустые реплики могут быть в статусе STARTUP2 - это означает, что на
256 них идёт копирование данных. При завершении копирования статус этой
257 реплики смениться на SECONDARY.
258
259
260
at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:80)
at kz.greetgo.md_reader.core.MdConverter.prepareHtmlFileFrom(MdConverter.java:136)
at kz.greetgo.md_reader.core.MdConverter.convert(MdConverter.java:208)
at kz.greetgo.md_reader.controller.RenderController.downloadToc(RenderController.java:360)
at kz.greetgo.md_reader.controller.RenderController.request(RenderController.java:108)
at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at kz.greetgo.md_reader.interceptors.TextReplaceFilter.doFilter(TextReplaceFilter.java:36)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.io.IOException: Server returned HTTP response code: 429 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:2000)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1397)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1333)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.startPE(XMLDTDScannerImpl.java:732)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.skipSeparator(XMLDTDScannerImpl.java:2101)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:2064)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDExternalSubset(XMLDTDScannerImpl.java:299)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1165)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1040)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:943)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:247)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:342)
at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:122)
at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:71)
... 48 more