MongoDB 데이터베이스 파일 크기 줄이기


165

한때 큰 (> 3GB) MongoDB 데이터베이스가 있습니다. 그 이후로 문서가 삭제되었으며 이에 따라 데이터베이스 파일의 크기가 줄어들 것으로 예상했습니다.

그러나 MongoDB는 할당 된 공간을 유지하므로 파일이 여전히 큽니다.

여기에서 admin 명령 mongod --repair이 사용되지 않은 공간을 비우는 데 사용 된다는 것을 읽었 지만 디스크 에이 명령을 실행하기에 충분한 공간이 없습니다.

사용하지 않는 공간을 확보 할 수있는 방법을 알고 있습니까?


7
이 질문에 대한 답변이 있습니까? 더 많은 데이터가 필요합니까?
Gates VP

2
2.8 버전부터는 데이터를 압축하여 공간을 크게 절약 할 수 있습니다 .
살바도르 달리

1
나는 똑같은 도전을했고, 그것을 해결하는 가장 쉬운 방법은 copyDatabase () 함수를 사용하여 데이터베이스의 사본을 만든 다음 db.dropDatabase () 원래 데이터베이스를 만든 다음 데이터베이스를 다시 복사하는 것이 었습니다. 내 데이터베이스는 대부분 비어 있었고 복사를 할 때 실제 사용 가능한 데이터 만 복사되었습니다. 원본 데이터베이스를 삭제하면 큰 파일이 삭제되었습니다. 내 서버의 디스크 공간이 부족하여 db.repairDatabase ()를 사용하는 것은 옵션이 아니 었으며이 작업에는이 작업에 필요한 것보다 훨씬 많은 여유 공간이 필요했습니다.
user3892260

답변:


144

업데이트 :compact명령 같은 WiredTiger 그것은 본다 추가 디스크 공간이 실제로 OS에 발표 될 예정이다 .


업데이트 : v1.9 이상에서는 compact명령이 있습니다.

이 명령은 "인라인"압축을 수행합니다. 여전히 여분의 공간이 필요하지만 그다지 많지는 않습니다.


MongoDB는 다음을 통해 파일을 압축합니다.

  • 파일을 새 위치로 복사
  • 문서 반복 및 재주문 / 재 해결
  • 원본 파일을 새 파일로 교체

실행 mongod --repair하거나 직접 연결하고 실행 하여이 "압축"을 수행 할 수 있습니다 db.repairDatabase().

두 경우 모두 파일을 복사 할 공간이 필요합니다. 이제 압축을 수행하기에 충분한 공간이없는 이유를 모르겠지만 공간이 더 많은 다른 컴퓨터가있는 경우 몇 가지 옵션이 있습니다.

  1. 를 사용하여 Mongo가 설치된 다른 컴퓨터로 데이터베이스를 내 보낸 mongoexport다음 (를 사용하여 mongoimport) 동일한 데이터베이스를 가져올 수 있습니다 . 그러면 압축 된 새 데이터베이스가 생성됩니다. 이제 mongod새 데이터베이스 파일로 원래 바꾸기를 중지 할 수 있습니다 .
  2. 현재 mongod를 중지하고 데이터베이스 파일을 더 큰 컴퓨터에 복사 한 후 해당 컴퓨터에서 복구를 실행하십시오. 그런 다음 새 데이터베이스 파일을 원래 컴퓨터로 다시 이동할 수 있습니다.

현재 몽고를 사용하여 "컴팩트 한 위치에"적합한 방법은 없습니다. 그리고 몽고는 확실히 많은 공간을 빨아 들일 수 있습니다.

압축을위한 최고의 전략은 Master-Slave 설정을 실행하는 것입니다. 그런 다음 슬레이브를 압축하여 따라 잡고 전환 할 수 있습니다. 나는 아직도 약간 털이 알고 있습니다. 아마도 몽고 팀이 압축을 더 잘 할 수는 있지만 목록에서 높은 것으로 생각하지는 않습니다. 드라이브 공간은 현재 저렴하다고 가정합니다 (보통).


답변 해 주신 Gates VP에게 감사드립니다. 나는 당신이 언급 한 두 가지 옵션을 생각하고있었습니다. 그러나 그런 일을하기 전에 컴팩트 한 솔루션을 사용할 수 있는지 알고 싶었습니다. 다시 감사합니다.
Meuble

3
오늘 (2010-11-18) 현재 Dwight (워싱턴 DC의 MongoDC 이벤트에서 연설)는 데이터베이스를 오프라인으로 만들지 않고 압축하려는 경우 replicate / --repair / switch over 방식을 권장했습니다.
David J.

10
'나처럼하지 마라'는 말만하고 뿌리로 수리를 실행하십시오. db 파일을 루트에 넣습니다. 도.
Totoro

18
'compact'에 대한 문서는 "이 작업은 파일 시스템에서 사용되는 디스크 공간의 양을 줄이지 않습니다."라고 말합니다. 이것이 원래의 질문에 대한 해결책인지 이해하지 못합니다.
Ed Norris

원래 질문을 보면 문제의 일부에 수리를 수행하기에 너무 많은 데이터가 포함되어있었습니다. 하나의 DB로 드라이브의 2/3를 채운 경우 복구를 수행 할 수 없습니다. 새로 할당 된 파일은 새 DB가 완전히 "복사 및 복구"되고 "스위치"가 발생하기 전에 남은 공간을 빨아들입니다. 로 compact기존 파일을 적어도 유지할 수 있습니다. 나는 이것이 완전한 솔루션은 아니지만 점진적으로 개선된다는 것에 동의합니다.
Gates VP

39

나는 같은 문제를 겪었고 단순히 명령 줄 에서이 작업을 수행하여 해결했습니다.

mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename

어설 션 : 15936 컬렉션 db.collection 생성에 실패했습니다. Errmsg : 예외 : capped가 true 일 때 size : <n> 지정
tweak2

: 우분투 회귀처럼 보입니다 ... 덤프 파일에 메타 데이터가 캡핑되었습니다 : "정의되지 않음"... 이러한 파일을 삭제하면 가져 오기 문제가 해결됩니다.
tweak2

2
내 데이터베이스는 거의 전체 디스크를 득점했습니다. 120GB (디스크 160GB) 콤팩트는 파일 크기를 줄이지 않으며 공간 부족으로 인해 데이터베이스를 복구 할 수 없습니다. db의 mongodump & dropDatabase & mongorestore 후에는 데이터베이스 크기가 40GB입니다.
Igor Benikov

복원 명령에 대한 작은 수정mongorestore --db databasename dump/databasename
JERRY

34

Mongo v1.9 +가 컴팩트를 지원하는 것처럼 보입니다!

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

http://docs.mongodb.org/manual/reference/command/compact/ 문서를 참조하십시오.

"repairDatabase와 달리, 컴팩트 명령은 작업을 수행하기 위해 이중 디스크 공간이 필요하지 않습니다. 작업하는 동안 적은 양의 추가 공간이 필요합니다. 또한 컴팩트가 빠릅니다."


3
@AnujGupta "repairDatabase 명령은 데이터베이스의 모든 콜렉션을 압축합니다. 각 콜렉션에서 개별적으로 컴팩트 명령을 실행하는 것과 동일합니다." docs.mongodb.org/manual/reference/command/repairDatabase/… . 따라서 repairDatabase가 크기를 작게 줄이면 매주 많은 삭제 및 업데이트로 컬렉션을 압축하고 있습니다. 나는 전체 데이터베이스가 아닌 컬렉션을 대상으로하기 때문에 repariDatabase보다 컴팩트 한 것을 더 좋아합니다. 둘째, db 파일 크기의 x2 (내 경우에는 500GB) 대신 2GB의 여유 공간이 필요합니다.
Maziyar

1
Btw check this : "MongoDB는 데이터를 압축하고 최적의 성능을 복원하는 두 가지 방법 인 repairDatabase와 compact를 제공합니다. RepairDatabase는 데이터베이스가 상대적으로 작거나 노드를 꽤 오랫동안 교체 할 수있는 경우에 적합합니다. 데이터베이스 크기 및 쿼리 워크로드의 경우 모든 컬렉션에 대해 지속적인 압축을 실행하는 것이 더 합리적입니다. " blog.parse.com/2013/03/26/always-be-compacting github.com/ParsePlatform/Ops/blob/master/tools/mongo_compact.rb
Maziyar

3
@Maziyar docs.mongodb.org/manual/reference/command/compact/#disk-space- "repairDatabase와 달리 compact는 파일 시스템의 공간을 비우지 않습니다".
Anuj Gupta

4
@Maziyar 영업 이익은하고 싶어 하지 않는 공간 확보 를 통해 달성, repairDatabase하지를 compact. compact공간을 늘리지 않고 사용한 공간을 조각 모음하기 만하면 공간이 줄어 듭니다.
Anuj Gupta

5
mongo 3.0부터 WiredTiger 스토리지 엔진을 사용하는 경우 공간 compact 확보합니다.
Gary

19

현재 데이터베이스의 모든 컬렉션 압축

db.getCollectionNames().forEach(function (collectionName) {
    print('Compacting: ' + collectionName);
    db.runCommand({ compact: collectionName });
});

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


7

StorageEngine을 기반으로 두 가지 방법을 풀어야합니다.

1. MMAP () 엔진 :

명령 : db.repairDatabase ()

참고 : repairDatabase에는 현재 데이터 세트 크기에 2GB를 더한 여유 디스크 공간이 필요합니다. dbpath를 보유한 볼륨에 충분한 공간이 없으면 별도의 볼륨을 마운트하고 복구에 사용할 수 있습니다. repairDatabase에 별도의 볼륨을 마운트 할 때는 명령 줄에서 repairDatabase를 실행하고 --repairpath 스위치를 사용하여 임시 복구 파일을 저장할 폴더를 지정해야합니다. 예 : DB 크기가 120GB를 의미한다고 가정하면 (120 * 2) +2 = 242GB 하드 디스크 공간이 필요합니다.

컬렉션을 현명하게 수행하는 다른 방법은 다음과 같습니다. db.runCommand ({compact : 'collectionName'})

2. WiredTiger : 자동으로 자체 해결됩니다.


6

MongoDB에서 공간 회수에 대해 상당한 혼란이 있었고 일부 권장 사례는 특정 배포 유형에서 매우 위험합니다. 자세한 내용은 아래를 참조하십시오.

TL; DR repairDatabase 은 디스크 손상으로부터 복구하려고하는 독립 실행 형 MongoDB 배치에서 데이터를 복구하려고 시도합니다. 공간을 복구하면 순전히 부작용 입니다. 공간 복구는 절대로 실행을 고려해야합니다 repairDatabase.

독립형 노드에서 공간 복구

WiredTiger : WiredTiger 를 사용하는 독립형 노드의 경우 실행시 compact한 가지 경고와 함께 OS에 공간이 해제 compact됩니다. MongoDB 3.0.x의 WiredTiger 명령은 다음 버그의 영향을받습니다. SERVER-21833 : MongoDB 3.2.3에서 수정되었습니다. 이 버전 이전에는 compactWiredTiger에서 자동으로 실패 할 수있었습니다.

MMAPv1 : MMAPv1 작동 방식으로 인해 MMAPv1 스토리지 엔진을 사용하여 공간을 복구하는 안전하고 지원되는 방법이 없습니다. compactMMAPv1에서는 데이터 파일 조각 모음을 수행하여 새 문서에 더 많은 공간을 사용할 수 있지만 OS에 공간을 다시 제공하지는 않습니다.

당신은 할 수있다 실행할 수 repairDatabase완전히 이것의 결과 이해하는 경우 잠재적으로 위험한 명령을하기 때문에, (아래 참조)repairDatabase 기본적으로 손상된 문서를 폐기하여 전체 데이터베이스를 다시 작성합니다. 부작용으로 새로운 MMAPv1 데이터 파일이 조각화되지 않고 OS에 공간이 다시 제공됩니다.

덜 모험 방법, 실행 mongodump하고하는 것은 mongorestore배포의 크기에 MMAPv1 배포, 주제에뿐만 아니라 가능하다.

복제 세트에서 공간 복구

복제 세트 구성의 경우 공간을 복구하는 가장 안전하고 안전한 방법은 WiredTiger와 MMAPv1 모두에 대해 초기 동기화 를 수행하는 것입니다.

세트의 모든 노드에서 공간을 복구해야하는 경우 롤링 초기 동기화를 수행 할 수 있습니다. 즉, 각 보조 노드에서 초기 동기화를 수행 한 후 최종적으로 기본 서버를 종료하고 초기 동기화를 수행하십시오. 롤링 초기 동기화 방법은 복제본 세트 유지 관리를 수행하는 가장 안전한 방법이며, 다운 타임을 추가로 포함하지 않습니다.

롤링 초기 동기화 수행 가능성은 배포 크기에 따라 다릅니다. 대규모 배포의 경우 초기 동기화를 수행 할 수 없으므로 옵션이 다소 제한적입니다. WiredTiger를 사용하는 경우, 당신은 할 수있다 , 세트의 하나 차 밖으로을 운영하는 독립형으로 시작할 수 compact그것을하고 세트에 다시 가입.

에 관해서 repairDatabase

repairDatabase복제 세트 노드에서 실행하지 마십시오 . repairDatabase 페이지 에서 언급했듯이 이것은 매우 위험 합니다 아래에서 더 자세히 설명 합니다.

repairDatabase명령이 아무것도 수리하려고 시도하지 않기 때문에 이름 이 약간 오도됩니다. 이 명령은 독립형 노드 에서 디스크가 손상되어 문서가 손상 될 수있는 경우에 사용되었습니다.

repairDatabase명령은 "salvage database"로보다 정확하게 설명 될 수 있습니다. 즉, 데이터베이스를 시작하고 손상되지 않은 문서를 구할 수있는 상태로 데이터베이스를 가져 오려는 시도에서 손상된 문서를 버려서 데이터베이스를 다시 작성합니다.

MMAPv1 배포에서 데이터베이스 파일의 이러한 재구성은 부작용으로 OS에 공간을 해제합니다 . OS 공간을 확보하는 것이 결코 목적이 아니 었습니다.

repairDatabase복제 세트에 대한 결과

복제 세트에서 MongoDB는 세트의 모든 노드가 동일한 데이터를 포함 할 것으로 예상합니다. repairDatabase복제 세트 노드에서 실행 하는 경우 노드에 감지되지 않은 손상이 포함되어있을 수 repairDatabase있으며 손상된 문서를 적절하게 제거합니다.

예상대로 노드에 나머지 세트와 다른 데이터 세트가 포함되어 있습니다. 업데이트가 해당 단일 문서에 도달하면 전체 세트가 충돌 할 수 있습니다.

설상가상으로,이 상황이 오랫동안 휴면 상태에있을 수 있으며 명백한 이유없이 갑자기 공격 할 수 있습니다.


5

콜렉션에서 많은 양의 데이터가 삭제되고 콜렉션이 새 문서에 대해 삭제 된 공간을 사용하지 않는 경우,이 공간은 운영 체제로 리턴되어 다른 데이터베이스 또는 콜렉션에서 사용할 수 있습니다. 디스크 공간 조각 모음을 수행하고 사용 가능한 여유 공간을 다시 확보하려면 압축 또는 복구 작업을 실행해야합니다.

압축 프로세스의 동작은 다음과 같이 MongoDB 엔진에 따라 다릅니다.

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

MMAPv1

압축 작업은 데이터 파일 및 인덱스 조각 모음을 수행합니다. 그러나 운영 체제에 공간을 확보하지는 않습니다. 이 작업은 여전히 ​​조각 모음을 수행하고 MongoDB에서 재사용 할 수 있도록 더 인접한 공간을 만드는 데 여전히 유용합니다. 그러나 사용 가능한 디스크 공간이 매우 적을 때는 아무 소용이 없습니다.

압축 작업 중에 최대 2GB의 추가 디스크 공간이 필요합니다.

압축 작업 중에는 데이터베이스 수준 잠금이 유지됩니다.

유선 타이거

WiredTiger 엔진은 기본적으로 MMAPv1보다 적은 디스크 공간을 사용하는 압축을 제공합니다.

컴팩트 한 프로세스는 운영 체제에 여유 공간을 제공합니다. 컴팩트 작업을 실행하려면 최소 디스크 공간이 필요합니다. 또한 WiredTiger는 데이터베이스 수준 잠금이 필요하므로 데이터베이스의 모든 작업을 차단합니다.

들어 MMAPv1의 엔진, 컴팩트 도다는 운영 시스템에 공간을 반환하지. 사용하지 않는 공간을 해제하려면 복구 작업을 실행해야합니다.

db.runCommand({repairDatabase: 1})

3

Mongodb 3.0 이상에는 새로운 스토리지 엔진 인 WiredTiger가 있습니다. 필자의 경우 스위칭 엔진은 디스크 사용량을 100Gb에서 25Gb로 줄였습니다.


1

데이터베이스 파일의 크기를 줄일 수 없습니다. 데이터베이스를 "복구"하는 동안 mongo 서버는 해당 파일 중 일부만 삭제할 수 있습니다. 많은 양의 데이터가 삭제 된 경우 mongo 서버는 복구 중에 기존 파일 중 일부를 "릴리스"(삭제)합니다.


1

일반적으로 데이터베이스를 복구하려면 컴팩트가 좋습니다. 그러나 압축에 비해 복구의 한 가지 장점은 전체 클러스터에 복구를 실행할 수 있다는 것입니다. 컴팩트하면 각 샤드에 로그인해야하는데, 이는 성가신 일입니다.


1

같은 문제가 발생했을 때 몽고 서버를 중지하고 명령으로 다시 시작했습니다.

mongod --repair

복구 작업을 실행하기 전에 HDD에 충분한 여유 공간이 있는지 확인해야합니다 (최소-데이터베이스 크기).


1

독립형 모드의 경우 압축 또는 복구를 사용할 수 있습니다.

샤드 클러스터 또는 복제 세트의 경우 필자의 경험에 따르면 기본에서 압축을 실행 한 후 보조를 압축하면 기본 데이터베이스의 크기는 줄어들지 만 보조 데이터베이스는 축소되지 않습니다. 하고 싶을 수도 있습니다보조 데이터베이스의 크기를 줄이기 위해 멤버 재 동기화 . 이 작업을 수행하면 보조 데이터베이스의 크기가 기본 데이터베이스보다 훨씬 줄어 듭니다. 압축 명령이 실제로 컬렉션을 압축하지 않는 것 같습니다. 그래서 복제본 세트의 기본 및 보조를 전환하고 다시 동기화 멤버를 수행 했습니다.

내 결론은 샤드 / 복제 세트의 크기를 줄이는 가장 좋은 방법은 재 동기화 멤버를 수행하고 기본 보조 스위치를 전환 한 다음 다시 동기화하는 것입니다.


0

샤드 클러스터의 경우 mongoDB -repair를 권장하지 않습니다.

replica set 샤드 클러스터를 사용하는 경우 compact 명령을 사용하면 모든 콜렉션의 모든 데이터 및 색인 파일을 다시 작성하고 조각 모음을 수행합니다. 통사론:

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

force : true와 함께 사용하면 기본 복제본 세트에서 압축이 실행됩니다. 예 : db.runCommand ( { command : "collection_name", force : true } )

고려해야 할 기타 사항 :-작업을 차단합니다. 유지 관리 기간에서 실행하는 것이 좋습니다. -다양한 서버에서 실행되는 복제 세트가 각 멤버에서 별도로 실행되어야하는 경우-샤드 클러스터의 경우 각 샤드 멤버에서 개별적으로 Compact가 실행되어야합니다. mongos 인스턴스에 대해 실행할 수 없습니다.


-5

내가 할 수있는 한 가지 방법. 기존 데이터의 안전성을 보장하지 않습니다. 자신의 위험을 감수하십시오.

데이터 파일을 직접 삭제하고 mongod를 다시 시작하십시오.

예를 들어, 우분투 (데이터의 기본 경로 : / var / lib / mongodb)를 사용하면 collection. #과 같은 이름의 파일이 몇 개 있습니다. 컬렉션을 유지하고 0을 모두 삭제했습니다.

데이터베이스에 심각한 데이터가없는 경우 더 쉬운 방법 인 것 같습니다.


파일은 <database_name>. <number> (예 : mydb.3)로 저장됩니다. 컬렉션을 말할 수 없습니다.
bobmarksie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.