실수로 마지막 쿼리에서 일부 문서를 제거했습니다. 마지막 쿼리 문합 컬렉션을 롤백 할 수있는 방법이 있습니까?MongoDB에서 최근에 삭제 된 문서를 복구 할 수있는 방법이 있습니까?
db.datas.remove({ "name" : "some_x_name"})
어떤 롤백/취소 옵션이 있습니다 :
은 여기 내 마지막 쿼리입니다? 내 데이터를 다시 가져올 수 있습니까?
실수로 마지막 쿼리에서 일부 문서를 제거했습니다. 마지막 쿼리 문합 컬렉션을 롤백 할 수있는 방법이 있습니까?MongoDB에서 최근에 삭제 된 문서를 복구 할 수있는 방법이 있습니까?
db.datas.remove({ "name" : "some_x_name"})
어떤 롤백/취소 옵션이 있습니다 :
은 여기 내 마지막 쿼리입니다? 내 데이터를 다시 가져올 수 있습니까?
MongoDB 컨텍스트에서 롤백 옵션 (rollback has a different meaning)이 없으며 엄밀히 말하자면이 문서를 다시 얻을 수있는 지원 방법이 없습니다. 수행 할 수있는 예방 조치는 주석에서 다루고 있습니다. 그렇지만 복제본 집합을 실행하는 경우 단일 노드 복제본 집합이라도 실행하면 oplog
이됩니다. 문서를 삽입 할 때 다루는 oplog
을 사용하면 문서를 복구 할 수 있습니다.
가장 쉬운 방법은 예제를 사용하는 것입니다. 복원해야하는 100 개의 삭제 된 문서가있는 단순화 된 예제를 사용합니다. 이것 (엄청난 수의 문서 또는 아마도 선택적으로 복원 만하기를 원할 것입니다)을 넘어서려면 커서를 반복하도록 코드를 변경하거나 MongoDB 셸 외부에서 선택한 언어를 사용하여 코드를 작성해야합니다. 기본 논리는 동일하게 유지됩니다.
우선 데이터베이스 dropTest
에 예제 콜렉션 foo
을 생성 해 보겠습니다.
> db.foo.remove({ "name" : "some_x_name"})
WriteResult({ "nRemoved" : 100 })
:
use dropTest;
for(i=0; i < 100; i++){db.foo.insert({_id : i})};
for(i=100; i < 200; i++){db.foo.insert({_id : i, name : "some_x_name"})};
을 이제 100 개 name
문서의 실수로 제거를 시뮬레이션하자 : 그들은 실수로 나중에 제거 할 수 있도록 우리는 name
필드가없는 (100 개) 문서와 동일한 name
필드 (100 개) 문서를 삽입합니다
우리는 복제 세트에서 실행되기 때문에, 우리는 여전히이 012,350,298,293 (삽입) 및 고맙게도 그 삽입이 없습니다 (아직)를 oplog
합니다 (oplog
의 마지막을 지나고 떨어진입니다 oplog
에서이 문서의 기록을 가지고기억). 우리가 그들을 찾을 수 있는지 보자 :
use local;
db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}).count();
100
개수가 정확하다고 보이지만 우리는 여전히 문서를 가지고있는 것 같습니다. 나는 우리가 여기에 필요합니다 oplog
항목의 유일한 조각이 o
필드는 것을 경험을 통해 알고, 그래서 그 반환 단지에 돌출부를 추가 할 수 있도록 (간결 냈다 출력을,하지만 당신은 아이디어를 얻을) :
db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}, {"o" : 1});
{ "o" : { "_id" : 100, "name" : "some_x_name" } }
{ "o" : { "_id" : 101, "name" : "some_x_name" } }
{ "o" : { "_id" : 102, "name" : "some_x_name" } }
{ "o" : { "_id" : 103, "name" : "some_x_name" } }
{ "o" : { "_id" : 104, "name" : "some_x_name" } }
이러한 문서를 다시 삽입하려면 배열에 저장 한 다음 배열을 반복하고 관련 조각을 삽입하면됩니다.
var deletedDocs = db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}, {"o" : 1}).toArray();
> deletedDocs.length
100
다음으로 우리는 지금 컬렉션의 100 개 삽입을 통해 다음 루프 (100 개) 문서를 가지고 자신을 생각 나게하고, 마지막으로 우리의 카운트 재 검증 : 첫째, 우리의 배열을 만들 수
use dropTest;
db.foo.count();
100
// simple for loop to re-insert the relevant elements
for (var i = 0; i < deletedDocs.length; i++) {
db.foo.insert({_id : deletedDocs[i].o._id, name : deletedDocs[i].o.name});
}
// check total and name counts again
db.foo.count();
200
db.foo.count({name : "some_x_name"})
100
을 그리고 거기 당신은 몇 가지주의와, 그것을 가지고 :이 코멘트에서 언급 한 바와 같이, 백업 (MMS, 기타) 그것에 대해, 지연 세컨더리 보면, 진정한 복원하는 전략으로 의미하지 않는다
oplog
의 형식은 내부 간주됩니다 및 변경 될 수 있습니다 시간 (예고없이)이므로 사용에 따른 모든 책임은 사용자에게 있습니다.나는 이것이 약간 낡았다는 것을 이해하지만 비슷한 문제를 가진 다른 사람들에게 유용 할 수있는이 분야에서 연구 한 것을 나눠보고 싶었습니다.
MongoDB는 실제로 데이터를 물리적으로 삭제하지 않습니다. 단지 삭제만을 표시합니다. 그러나 이는 버전에 따라 다르며 현재는 설명서 나 표준화가 없으므로 타사 도구 개발자 (또는 절실히 필요로하는 사람)가 도구를 작성하거나 여러 버전에서 작동하는 간단한 스크립트를 안정적으로 작성할 수 있습니다. 이 티켓을 열었습니다 - https://jira.mongodb.org/browse/DOCS-5151.
훨씬 낮은 레벨에있는 하나의 옵션을 탐색하여 사용 된 MongoDB의 버전에 따라 미세 조정이 필요할 수 있습니다. 이해하기 쉽지만 대부분의 사람들이 연결하기에는 너무 낮은 수준이지만 작동하고 다른 모든 것이 실패 할 때 편리 할 수 있습니다.
내 접근 방식은 파일에서 바이너리를 직접 사용하고 파이썬 스크립트 (또는 명령)를 사용하여 삭제 된 데이터를 식별, 읽기 및 압축 해제 (BSON)합니다.
내 접근 방식은 this GitHub 프로젝트에서 영감을 받았습니다 (본인은이 프로젝트의 개발자가 아닙니다). Here on my blog 나는 스크립트를 단순화하고 Raw MongoDB 파일에서 특정 삭제 된 레코드를 추출하려고 시도했다.
현재 레코드 시작 부분에 "\xee
"으로 삭제 표시가되어 있습니다. 이
‘\xee\xee\xee\xee\x07_id\x00U\x19\xa6g\x9f\xdf\x19\xc1\xads\xdb\xa8\x02name\x00\x04\x00\x00\x00AAA\x00\x01marks\x00\x00\x00\x00\x00\[email protected]\[email protected]\x00′
은 내가 다른 기록에 따라 이전에 확인 된 레코드의 크기로 첫 번째 블록을 교체, 삭제 된 레코드가 원시 DB 파일의 모습입니다.
y=”3\x00\x00\x00″+x[20804:20800+51]
마지막으로 BSON 패키지 (pymongo와 함께 제공됨)를 사용하여 Readable 객체에 바이너리를 디코딩했습니다.
bson.decode_all(y)
[{u’_id': ObjectId(‘5519a6679fdf19c1ad73dba8′), u’name': u’AAA’, u’marks': 2000.0}]
이 BSON은 현재 파이썬 개체이며 복구 컬렉션에 덤프되거나 단순히 어딘지에 기록 될 수 있습니다.
이 복구 기술이나 다른 복구 기술은 데이터베이스 파일의 백업 복사본에있는 준비 영역에서 이상적으로 수행되어야합니다.
답변 해 주셔서 감사합니다! 드문 정보입니다. 정말 도움이 되겠습니까 !! – trex
환영합니다 - 필자는 필자가 작성한 논문의 일부로 Apache Cassandra와 Apache HBase를 사용하여 다양한 수준의 성공을 거두는 방법을 모색했다. –
나는 아주 큰 데이터 덤프를 복구해야하고 위의 링크 주먹은 Mongo 2.4에서 삭제 된 레코드를 올바르게 처리하지 못합니다. @ YazadKhambata가 올바르게 수행했습니다. 그래서 저는 Yazad의 정보를 가지고 요지에서 스크립트를 다시 작성하고 https://gist.github.com/guss77/f8e610cfddbe02c07896을 얻었습니다. 필자는 큰 삭제 된 컬렉션에서 수천 개의 레코드를 복구하는 데이 방법을 사용했습니다. – Guss
중요한 데이터를 작성하는 경우 정기적 인 백업을 수행하는 것이 중요합니다. 이것은 모든 데이터베이스 기술에 적용됩니다. – Sammaye
백업은 항상 좋은 생각이지만 지연과 함께 복제본을 실행하여 최근과 같은 과거의 실수를 수정할 수있는 옵션을 제공합니다. http://docs.mongodb.org/manual/tutorial/configure-a-delayed-replica-set-member/ –
MMS를 사용한 경우 특정 시점 복원을 수행 할 수있었습니다. 롤백 할 다른 방법은 없습니다 !!!! – vmr