[mongodb] 오버플로 정렬 단계 버퍼링 된 데이터 사용량이 내부 제한을 초과 함

코드 사용 :

all_reviews = db_handle.find().sort('reviewDate', pymongo.ASCENDING)
print all_reviews.count()

print all_reviews[0]
print all_reviews[2000000]

카운트가 인쇄 2043484되고 인쇄 all_reviews[0]됩니다.

그러나 인쇄 할 때 all_reviews[2000000]오류가 발생합니다.

pymongo.errors.OperationFailure : 데이터베이스 오류 : Runner 오류 : 33554495 바이트의 오버플로 정렬 단계 버퍼링 된 데이터 사용량이 33554432 바이트의 내부 제한을 초과합니다.

어떻게 처리합니까?



답변

메모리 내 정렬에서 32MB 제한에 도달했습니다.

https://docs.mongodb.com/manual/reference/limits/#Sort-Operations

정렬 필드에 색인을 추가하십시오. 이를 통해 MongoDB는 문서를 모두 서버의 메모리에로드하고 클라이언트로 보내기 전에 메모리에서 정렬하지 않고 정렬 된 순서로 문서를 스트리밍 할 수 있습니다.


답변

kumar_harsh댓글 섹션에서 말했듯이 다른 요점을 추가하고 싶습니다.

admin데이터베이스 에서 아래 명령을 사용하여 현재 버퍼 사용량을 볼 수 있습니다 .

> use admin
switched to db admin
> db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )
{ "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 }

기본값은 32MB (33554432 바이트)입니다 .이 경우 버퍼 데이터가 부족하므로 자신이 정의한 최적 값 (예 : 아래와 같이 50MB)으로 버퍼 제한을 늘릴 수 있습니다.

>  db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432})
{ "was" : 33554432, "ok" : 1 }

mongodb 구성 파일의 아래 매개 변수로이 제한을 영구적으로 설정할 수도 있습니다.

setParameter=internalQueryExecMaxBlockingSortBytes=309715200

도움이 되었기를 바랍니다 !!!

Note:이 명령은 버전 3.0 이상에서만 지원됩니다.


답변

인덱싱으로 해결

db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])


답변

인덱스 생성을 피하고 싶다면 (예 : 데이터를 탐색하기 위해 빠르고 간단하게 확인하려는 경우) 디스크 사용량과 함께 집계를 사용할 수 있습니다.

all_reviews = db_handle.aggregate([{$sort: {'reviewDate': 1}}], {allowDiskUse: true})

(그러나 pymongo에서 이것을 수행하는 방법을 모르겠습니다).


답변

색인에 대한 JavaScript API 구문 :

db_handle.ensureIndex({executedDate: 1})


답변

제 경우에는 코드에서 필수 인덱스를 수정하고 다시 만들어야했습니다.

rake db:mongoid:create_indexes RAILS_ENV=production

필요한 필드 인덱스가있을 때 메모리 오버플로가 발생하지 않기 때문에.

추신 이전에는 긴 인덱스를 만들 때 오류를 비활성화해야했습니다.

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )

또한 필요할 수 있습니다 reIndex.

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> use your_db
switched to db your_db
> db.getCollectionNames().forEach( function(collection){ db[collection].reIndex() } )


답변