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


85

코드 사용 :

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 바이트의 내부 제한을 초과합니다.

어떻게 처리합니까?

답변:


118

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

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

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


7
RAM에서 정렬 할 필요가 없도록 인덱스를 선언하는 것이 좋습니다. 잠재적으로 무제한이 아닌 더 빠르고 안정적이며 제한된 RAM 사용입니다. 주장한다면 "find"를 집계 (정렬에 100MB의 RAM을 사용할 수 있음)로 전환하고 allowDiskUse : true를 설정하여 100MB의 RAM을 초과 할 경우 집계 프레임 워크가 디스크로 유출되도록합니다. 적절한 인덱스를 선언하는 것보다 심각한 성능 저하를 예상합니다. docs.mongodb.org/manual/reference/operator/aggregation/sort/…
A. Jesse Jiryu Davis

31
실제로는 변경할 수 있습니다. 다음 명령을 실행해야합니다 db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes: <limit in bytes>}).. 출처 : askubuntu.com/questions/501937/…
kumarharsh

6
mongoose 사용자에게는 스키마의 prop에 index : true를 설정하면이 문제가 해결된다는 점을 알아두면 좋습니다. mongoose는 모든 스키마를 살펴보고 앱을 시작하기 전에 필드가 실제로 색인인지 확인합니다. mySchema.set ( 'autoIndex', false)를 사용하여이 동작을 해제합니다.
벤자민 코 넌트

2
정렬 필드에 인덱스를 만들었지 만 "정렬 작업이 RAM의 최대 33554432 바이트 이상을 사용했습니다"라는 오류가 발생하는 이유는 정렬 전에 일치 작업을 적용하고 정렬하기 전에 일치를 사용하는 경우 mongo doc에 따라 발생하기 때문일 수 있습니다. 작업은 인덱스를 무시하고 일치하는 모든 레코드에 대해 메모리 정렬을 수행합니다.
Amol Suryawanshi

11
이것이 허용되는 대답이라면 색인을 추가하는 방법에 대한 정보를 포함해야합니다.
Philipp Ludwig

45

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 이상에서만 지원됩니다.


구성 파일에서이 제한을 영구적으로 설정하는 방법은 무엇입니까? mongo 전용 1TB 메모리 머신이 있는데 영구적으로 크랭크업하고 싶습니다.
Samantha Atkins

@SamanthaAtkins 구성 파일에서 영구적으로 설정하도록 답변을 업데이트했습니다.
JERRY

@JERRY 레일에 영구적으로 설정할 위치. Rails 5 / mongoid.yml?
Prateep Kul

찾았어요. 내 터미널에서 실행 : mongod
Prateep Kul

24

인덱싱으로 해결

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

확인 스파 스 인덱스를 사용하지 수, 그들은 무시하는 경우 종류의 모든 문서에
CHARLY 코자

15

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

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

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


pymongo에서는 db_handle.aggregate(pipe, allowDiskUse=True). 자세한 내용은 이 질문 을 참조하십시오!
Genarito

3

색인에 대한 JavaScript API 구문 :

db_handle.ensureIndex({executedDate: 1})

2

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

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() } )
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.