オーバーフローソートステージのバッファデータ使用量が内部制限を超えています


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:データベースエラー:ランナーエラー:33554495バイトのオーバーフローソートステージのバッファデータ使用量が33554432バイトの内部制限を超えています

これをどのように処理しますか?

回答:


118

インメモリソートで32MBの制限に達しています:

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

ソートフィールドにインデックスを追加します。これにより、MongoDBは、クライアントに送信する前にすべてのドキュメントをサーバー上のメモリにロードしてメモリ内で並べ替えるのではなく、並べ替えられた順序でドキュメントをストリーミングできます。


7
RAMでソートする必要がないように、インデックスを宣言することをお勧めします。無制限ではなく、より高速で信頼性が高く、RAMの使用量が制限されます。主張する場合は、「検索」をアグリゲーション(100MBのRAMを使用してソートできます)に変換し、allowDiskUse:trueを設定して、100MBのRAMを超える場合にディスクにスピルするようにアグリゲーションフレームワークに指示します。適切なインデックスを宣言するだけの場合と比較して、パフォーマンスが大幅に低下することが予想されます。docs.mongodb.org/manual/reference/operator/aggregation/sort/…–
A. Jesse

31
実際には、変更することができます。次のコマンドを実行する必要があります:db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes: <limit in bytes>})。出典:askubuntu.com/questions/501937/...
kumarharsh

6
マングースユーザーにとって、スキーマの小道具にindex:trueを設定すると、この問題が修正されることに注意してください...マングースはすべてのスキーマを調べ、アプリを起動する前にフィールドが実際にインデックスであることを確認します... mySchema.set( 'autoIndex'、false);を使用してこの動作をオフにします。
ベンジャミンコナント2016

2
並べ替えフィールドにインデックスを作成しましたが、「並べ替え操作で最大33554432バイトのRAMを超えて使用されました」というエラーが表示されるのは、並べ替え前に一致操作を適用しているためであり、並べ替え前に一致を使用する場合はmongodocに準拠している可能性があります。操作はインデックスを無視し、一致したすべてのレコードに対してメモリ内で並べ替えを実行します。
Amol Suryawanshi 2018

11
これが受け入れられた回答である場合は、インデックスを追加する方法に関する情報を含める必要があります。
フィリップルートヴィヒ

45

で述べたようにkumar_harsh、コメントセクションでは、私は別のポイントを追加したいと思います。

adminデータベースに対して以下のコマンドを使用して、現在のバッファー使用量を表示できます。

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

デフォルト値は32MB(33554432バイト)です。この場合、バッファーデータが不足しているため、独自に定義した最適値(たとえば、以下のように50 MB)でバッファー制限を増やすことができます。

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

この制限は、mongodb構成ファイルの以下のパラメーターによって永続的に設定することもできます。

setParameter=internalQueryExecMaxBlockingSortBytes=309715200

お役に立てれば !!!

Note:このコマンドは、バージョン3.0以降でのみサポートされます。


設定ファイルでこの制限を永続的に設定する方法は何ですか?私はmongo専用の1TBメモリマシンを持っており、それを永続的にクランクアップしたいと思います。
サマンサアトキンス

@SamanthaAtkins回答を更新して、これを構成ファイルに永続的に設定しました。
JERRY 2018

@JERRYレールに永続的に設定する場所。Rails 5 / mongoid.yml?
プラティープクル

見つけた。私のターミナルで実行します。mongodは、マニュアルに従うzocada.com/setting-mongodb-users-beginners-guideを
プラティープクル

24

インデックス作成で解決

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

スパースインデックスは使用しないでください。すべてのドキュメントで並べ替えると無視されます
Charly Koza

15

インデックスの作成を避けたい場合(たとえば、データを調査するための手っ取り早いチェックが必要な場合)、ディスク使用量で集計を使用できます。

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

(ただし、pymongoでこれを行う方法はわかりません)。


pymongoではになりますdb_handle.aggregate(pipe, allowDiskUse=True)。詳細については、この質問を参照してください。
Genarito

3

インデックスのJavaScriptAPI構文:

db_handle.ensureIndex({executedDate: 1})

2

私の場合、コード内の必須インデックスを修正して再作成する必要がありました。

rake db:mongoid:create_indexes RAILS_ENV=production

必要なフィールドのインデックスがある場合、メモリオーバーフローは発生しません。

PSこれまでは、長いインデックスを作成するときにエラーを無効にする必要がありました。

# 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.