Backup and Recover

데이터의 안전한 사용과 값에 대한 일관성을 유지하기 위해 DB를 사용하게 된다. DB에 장애가 발생하였을 때 가장 요구되는 기능이 바로 백업/복구에 관련된 기능이다.

Types of MongoDB Backup/Recover

실습 데이터 생성

Enterprise test> for(var i=0;i<20;i++){
...   db.things.insertOne({x:4,j:i});
... }
{
  acknowledged: true,
  insertedId: ObjectId("63be64ad9c1ec58aadeaec51")
}
Enterprise test> db.things.find().count();
20

1. Shutdown & File Copy

NoSQL의 경우도 RDBMS와 마찬가지로 파일에 데이터를 저장하기 때문에, 해당 물리 파일을 복사/붙여넣기 하는 방식의 아주 기본적인 백업 방법이다. 단, 파일을 복제하는 것이므로 서비스를 모두 종료 시킨 상태에서 동작한다.(새로운 데이터가 유입되거나, 기존 데이터가 변경/삭제 될 경우 무결성에 문제가 생길 수 있기 때문에 DB 서비스를 완전히 종료한 다음에 진행하는 것이다.)

2. FsyncLock & Backup

FsyncLock는 DB에 락을 걸어 데이터를 복제한다. 서비스를 종료하지 않고 락을 걸어 새로운 데이터의 유입/변경/삭제를 차단하여 데이터 무결성의 문제를 해결한다. 백업/복구의 작업이 완료된 후에 락을 풀어 데이터 수정을 진행한다.

3. MongoDump, MongoRestore

가장 흔한 방식의 백업/복구 방식으로 데이터를 컬렉션, DB, 전체 DB 단위로 백업이 가능하며, 백업된 데이터는 BSON 형태로 저장되어 빠른 백업, 복구가 가능하다.

mongodump

C:\Program Files\MongoDB>mongodump --host 127.0.0.1
2023-01-11T16:36:24.496+0900    writing admin.system.version to dump\admin\system.version.bson
2023-01-11T16:36:24.602+0900    done dumping admin.system.version (1 document)
2023-01-11T16:36:24.603+0900    writing test.things to dump\test\things.bson
2023-01-11T16:36:24.603+0900    writing test.users to dump\test\users.bson
2023-01-11T16:36:24.603+0900    writing test.scores to dump\test\scores.bson
2023-01-11T16:36:24.603+0900    writing test.phones to dump\test\phones.bson
2023-01-11T16:36:24.604+0900    done dumping test.things (20 documents)
2023-01-11T16:36:24.605+0900    writing test.wordcount to dump\test\wordcount.bson
2023-01-11T16:36:24.606+0900    done dumping test.wordcount (4 documents)
2023-01-11T16:36:24.607+0900    writing test.pivot to dump\test\pivot.bson
2023-01-11T16:36:24.608+0900    done dumping test.pivot (4 documents)
2023-01-11T16:36:24.608+0900    writing test.actors to dump\test\actors.bson
2023-01-11T16:36:24.610+0900    done dumping test.actors (2 documents)
2023-01-11T16:36:24.610+0900    writing test.words to dump\test\words.bson
2023-01-11T16:36:24.616+0900    done dumping test.scores (13 documents)
2023-01-11T16:36:24.617+0900    writing config.tenantMigrationDonors to dump\config\tenantMigrationDonors.bson
2023-01-11T16:36:24.619+0900    done dumping test.words (2 documents)
2023-01-11T16:36:24.619+0900    writing config.tenantMigrationRecipients to dump\config\tenantMigrationRecipients.bson
2023-01-11T16:36:24.620+0900    done dumping config.tenantMigrationDonors (0 documents)
2023-01-11T16:36:24.621+0900    writing config.external_validation_keys to dump\config\external_validation_keys.bson
2023-01-11T16:36:24.622+0900    done dumping config.tenantMigrationRecipients (0 documents)
2023-01-11T16:36:24.624+0900    done dumping config.external_validation_keys (0 documents)
2023-01-11T16:36:24.724+0900    done dumping test.users (100000 documents)
2023-01-11T16:36:24.909+0900    done dumping test.phones (200000 documents)

C:\Program Files\MongoDB>dir
 C 드라이브의 볼륨: OS_Programs
 볼륨 일련 번호: 8CDA-0CC0

 C:\Program Files\MongoDB 디렉터리

2023-01-11  오후 04:36    <DIR>          .
2023-01-04  오전 12:30    <DIR>          ..
2023-01-11  오후 04:36    <DIR>          db
2023-01-02  오후 12:40    <DIR>          db2
2023-01-02  오후 12:39    <DIR>          db3
2023-01-11  오후 04:36    <DIR>          dump
2022-12-23  오전 01:49    <DIR>          Server
2022-12-23  오후 11:37    <DIR>          Shell
2023-01-11  오후 04:34    <DIR>          Tools
               0개 파일                   0 바이트
               9개 디렉터리  81,878,081,536 바이트 남음

mongodump_result

각각의 collection에 대해 bson 형태로 데이터가 백업된 것을 확인할 수 있다.

mongorestore

//DB 삭제
Enterprise test> db.dropDatabase()
{ ok: 1, dropped: 'test' }

Enterprise test> show collections


C:\Program Files\MongoDB>mongorestore --host 127.0.0.1 ./dump/
2023-01-11T16:46:13.745+0900    preparing collections to restore from
2023-01-11T16:46:13.787+0900    reading metadata for test.actors from dump\test\actors.metadata.json
2023-01-11T16:46:13.787+0900    reading metadata for test.phones from dump\test\phones.metadata.json
2023-01-11T16:46:13.788+0900    reading metadata for test.scores from dump\test\scores.metadata.json
2023-01-11T16:46:13.788+0900    reading metadata for test.users from dump\test\users.metadata.json
2023-01-11T16:46:13.788+0900    reading metadata for test.words from dump\test\words.metadata.json
2023-01-11T16:46:13.788+0900    reading metadata for config.tenantMigrationDonors from dump\config\tenantMigrationDonors.metadata.json
2023-01-11T16:46:13.788+0900    reading metadata for config.tenantMigrationRecipients from dump\config\tenantMigrationRecipients.metadata.json
2023-01-11T16:46:13.788+0900    reading metadata for test.things from dump\test\things.metadata.json
2023-01-11T16:46:13.789+0900    reading metadata for test.wordcount from dump\test\wordcount.metadata.json
2023-01-11T16:46:13.789+0900    reading metadata for config.external_validation_keys from dump\config\external_validation_keys.metadata.json
2023-01-11T16:46:13.789+0900    reading metadata for test.pivot from dump\test\pivot.metadata.json
2023-01-11T16:46:13.809+0900    restoring test.phones from dump\test\phones.bson
2023-01-11T16:46:13.813+0900    restoring test.users from dump\test\users.bson
2023-01-11T16:46:13.817+0900    restoring test.things from dump\test\things.bson
2023-01-11T16:46:13.820+0900    restoring test.scores from dump\test\scores.bson
2023-01-11T16:46:13.827+0900    finished restoring test.things (20 documents, 0 failures)
2023-01-11T16:46:13.831+0900    finished restoring test.scores (13 documents, 0 failures)
2023-01-11T16:46:13.835+0900    restoring test.pivot from dump\test\pivot.bson
2023-01-11T16:46:13.843+0900    restoring test.actors from dump\test\actors.bson
2023-01-11T16:46:13.846+0900    finished restoring test.pivot (4 documents, 0 failures)
2023-01-11T16:46:13.854+0900    finished restoring test.actors (2 documents, 0 failures)
2023-01-11T16:46:13.856+0900    restoring test.wordcount from dump\test\wordcount.bson
2023-01-11T16:46:13.863+0900    restoring test.words from dump\test\words.bson
2023-01-11T16:46:13.866+0900    finished restoring test.wordcount (4 documents, 0 failures)
2023-01-11T16:46:13.866+0900    restoring to existing collection config.external_validation_keys without dropping
2023-01-11T16:46:13.866+0900    restoring config.external_validation_keys from dump\config\external_validation_keys.bson
2023-01-11T16:46:13.874+0900    finished restoring test.words (2 documents, 0 failures)
2023-01-11T16:46:13.874+0900    restoring to existing collection config.tenantMigrationDonors without dropping
2023-01-11T16:46:13.874+0900    restoring config.tenantMigrationDonors from dump\config\tenantMigrationDonors.bson
2023-01-11T16:46:13.882+0900    finished restoring config.external_validation_keys (0 documents, 0 failures)
2023-01-11T16:46:13.882+0900    restoring to existing collection config.tenantMigrationRecipients without dropping
2023-01-11T16:46:13.882+0900    restoring config.tenantMigrationRecipients from dump\config\tenantMigrationRecipients.bson
2023-01-11T16:46:13.891+0900    finished restoring config.tenantMigrationDonors (0 documents, 0 failures)
2023-01-11T16:46:13.899+0900    finished restoring config.tenantMigrationRecipients (0 documents, 0 failures)
2023-01-11T16:46:14.787+0900    finished restoring test.users (100000 documents, 0 failures)
2023-01-11T16:46:15.697+0900    finished restoring test.phones (200000 documents, 0 failures)
2023-01-11T16:46:15.697+0900    no indexes to restore for collection test.scores
2023-01-11T16:46:15.697+0900    no indexes to restore for collection test.wordcount
2023-01-11T16:46:15.697+0900    no indexes to restore for collection test.pivot
2023-01-11T16:46:15.697+0900    no indexes to restore for collection test.actors
2023-01-11T16:46:15.697+0900    no indexes to restore for collection test.phones
2023-01-11T16:46:15.697+0900    restoring indexes for collection config.tenantMigrationDonors from metadata
2023-01-11T16:46:15.698+0900    index: &idx.IndexDocument{Options:primitive.M{"expireAfterSeconds":0, "name":"TenantMigrationDonorTTLIndex", "v":2}, Key:primitive.D{primitive.E{Key:"expireAt", Value:1}}, PartialFilterExpression:primitive.D(nil)}
2023-01-11T16:46:15.698+0900    restoring indexes for collection test.users from metadata
2023-01-11T16:46:15.698+0900    no indexes to restore for collection test.words
2023-01-11T16:46:15.698+0900    no indexes to restore for collection test.things
2023-01-11T16:46:15.698+0900    index: &idx.IndexDocument{Options:primitive.M{"name":"username_1", "v":2}, Key:primitive.D{primitive.E{Key:"username", Value:1}}, PartialFilterExpression:primitive.D(nil)}
2023-01-11T16:46:15.698+0900    restoring indexes for collection config.tenantMigrationRecipients from metadata
2023-01-11T16:46:15.698+0900    index: &idx.IndexDocument{Options:primitive.M{"expireAfterSeconds":0, "name":"TenantMigrationRecipientTTLIndex", "v":2}, Key:primitive.D{primitive.E{Key:"expireAt", Value:1}}, PartialFilterExpression:primitive.D(nil)}
2023-01-11T16:46:15.698+0900    restoring indexes for collection config.external_validation_keys from metadata
2023-01-11T16:46:15.698+0900    index: &idx.IndexDocument{Options:primitive.M{"expireAfterSeconds":0, "name":"ExternalKeysTTLIndex", "v":2}, Key:primitive.D{primitive.E{Key:"ttlExpiresAt", Value:1}}, PartialFilterExpression:primitive.D(nil)}
2023-01-11T16:46:15.824+0900    300045 document(s) restored successfully. 0 document(s) failed to restore.

//DB 복구 후 다시 조회를 했을 때 정상적으로 모든 collections이 복구되었음을 확인할 수 있다.
Enterprise test> show collections
actors
phones
pivot
scores
things
users
wordcount
words

4. MongoExport, MongoImport

위의 MongoDump, MongoRestore 와 유사한 방식인데, csv, tsv, 등의 다양한 형태의 데이터를 저장하는 것이 가능하다. BSON type 보다는 상대적으로 느린 부분이 있지만, 외부 툴을 활용할 수 있다는 점에서 호환성이 좋다.

mongoexport

test db 내에 things collection을 test.exp 파일에 백업하겠다.

C:\Program Files\MongoDB>mongoexport -h 127.0.0.1 -c things -d test -o "C:\Program Files\MongoDB\test.exp"
2023-01-11T16:41:34.070+0900    connected to: mongodb://127.0.0.1/
2023-01-11T16:41:34.110+0900    exported 20 records

test.exp

mongoexport을 통한 백업을 수행했을 때, json type으로 백업하는 것을 확인할 수 있다.

{"_id":{"$oid":"63be64ad9c1ec58aadeaec3e"},"x":4,"j":0}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec3f"},"x":4,"j":1}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec40"},"x":4,"j":2}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec41"},"x":4,"j":3}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec42"},"x":4,"j":4}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec43"},"x":4,"j":5}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec44"},"x":4,"j":6}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec45"},"x":4,"j":7}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec46"},"x":4,"j":8}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec47"},"x":4,"j":9}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec48"},"x":4,"j":10}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec49"},"x":4,"j":11}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec4a"},"x":4,"j":12}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec4b"},"x":4,"j":13}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec4c"},"x":4,"j":14}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec4d"},"x":4,"j":15}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec4e"},"x":4,"j":16}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec4f"},"x":4,"j":17}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec50"},"x":4,"j":18}
{"_id":{"$oid":"63be64ad9c1ec58aadeaec51"},"x":4,"j":19}

mongoimport

복구 수행

C:\Program Files\MongoDB>mongoimport -d test -c things --type json --file "C:\Program Files\MongoDB\test.exp"
2023-01-11T16:41:34.070+0900    connected to: mongodb://127.0.0.1/
2023-01-11T16:41:34.110+0900    exported 20 records

Enterprise test> db.things.drop();
true
Enterprise test> show collections
actors
phones
pivot
scores
users
wordcount
words
Enterprise test> db.things.find().count()
20

5. Primary, Secondary & Replica

Master node에 입력된 쿼리에 대해서 slave node에도 그대로 실행되게끔 하여 master node에 적용된 변경사항을 slave node에도 똑같이 적용하여 데이터 복제본을 실시간으로 유지한다. 다만, main 서버에 적용된 수정 쿼리가 slave에도 적용되기 때문에 쿼리 명령어를 통해 유실된 데이터를 복구할 수 없다.

Replication Set

MongoDB는 기본적으로 Primary 서버 + 2* Secondary 서버 형태인 Replication Set을 유지한 상태로 동작하기 때문에, primary 서버에서 문제가 발생하게 되면 sencondary 서버 간에 투표를 진행하여 새로운 primary 서버를 선출하게 된다. MongoDB에서는 이와 같은 방식으로 primary 서버가 오작동할 경우에 대비한다.

6. Snapshot 백업

MongoDB 내부에서 사용하는 백업 방식으로, 사용자의 데이터를 안전하게 저장하기 위한 버퍼을 활용한다. 데이터가 입력될 때 우선, 메모리 상의 Journal System에 해당 내용을 저장한 다음에 디스크에 데이터를 저장하게 되는데, 만일 디스크에 문제가 발생할 경우, Journal System에 기록된 내용을 바탕으로 해당 데이터를 복구한다.

References

댓글남기기