अतिप्रवाह सॉर्ट चरण बफ़र डेटा उपयोग आंतरिक सीमा से अधिक है


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

आप इन-मेमोरी सॉर्ट पर 32 एमबी की सीमा में चल रहे हैं:

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

सॉर्ट फ़ील्ड में कोई अनुक्रमणिका जोड़ें। यह MongoDB को क्रमबद्ध क्रम में दस्तावेज़ों को स्ट्रीम करने की अनुमति देता है, बजाय उन सभी को सर्वर पर मेमोरी में लोड करने के और क्लाइंट को भेजने से पहले उन्हें मेमोरी में सॉर्ट करने की अनुमति देता है।


7
एक इंडेक्स घोषित करने के लिए बेहतर है ताकि आपको रैम में सॉर्ट करने की आवश्यकता न हो: संभावित रूप से असीमित के बजाय तेजी से और अधिक विश्वसनीय, सीमित रैम उपयोग। यदि आप जोर देते हैं, तो अपने "ढूंढें" को एक एकत्रीकरण में बदल दें (जो सॉर्ट करने के लिए 100 एमबी रैम का उपयोग कर सकते हैं) और allowDiskUse सेट करें: डिस्क को फैलाने के लिए एकत्रीकरण ढांचे को बताने के लिए सही है यदि यह 100 एमबी रैम से अधिक है। एक उचित सूचकांक घोषित करने की तुलना में एक गंभीर प्रदर्शन दंड की अपेक्षा करें। docs.mongodb.org/manual/reference/operator/aggregation/sort/…
A. जेसी जिरू डेविस

31
दरअसल, इसे बदला जा सकता है। आपको इस कमांड को चलाने की आवश्यकता है db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes: <limit in bytes>}):। स्रोत: askubuntu.com/questions/501937/…
कुमारहर्ष

6
Mongoose उपयोगकर्ताओं के लिए नोट करने के लिए अच्छा है जो इंडेक्स सेट कर रहे हैं: आपके स्कीमा में प्रोप पर सही इस समस्या को ठीक करेगा ... mongoose आपके सभी स्कीमाओं के माध्यम से जाएगा और यह सुनिश्चित करेगा कि एप्लिकेशन प्रारंभ करने से पहले फ़ील्ड वास्तव में अनुक्रमित हैं ... जब तक कि आप mySchema.set ('autoIndex', false) के साथ इस व्यवहार को बंद कर देते हैं;
बेंजामिन कॉंटेंट

2
मैंने सॉर्टिंग फ़ील्ड पर एक इंडेक्स बनाया है, लेकिन फिर भी यह मुझे यह दे रहा है "अधिकतम 33554432 बाइट्स का उपयोग किया गया सॉर्ट ऑपरेशन" त्रुटि हो सकती है क्योंकि मैं छँटाई से पहले मैच ऑपरेशन लागू कर रहा हूं और मोंगो डॉक के अनुसार यदि आप सॉर्ट से पहले उपयोग करते हैं तो ऑपरेशन यह सूचकांक की उपेक्षा करेगा और सभी मिलान किए गए रिकॉर्ड से अधिक मेमोरी में प्रदर्शन करेगा।
अमोल सूर्यवंशी

11
यदि यह स्वीकृत उत्तर है, तो इसमें सूचकांक को जोड़ने के बारे में जानकारी शामिल होनी चाहिए।
फिलिप लुडविग

45

जैसा कि kumar_harshटिप्पणी अनुभाग में कहा गया है, मैं एक और बिंदु जोड़ना चाहूंगा।

आप adminडेटाबेस पर नीचे दिए गए कमांड का उपयोग करके वर्तमान बफर उपयोग देख सकते हैं :

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

इसका डिफ़ॉल्ट मान 32 MB (33554432 बाइट्स) है । इस मामले में आप बफर डेटा की कमी से भाग रहे हैं ताकि आप अपने स्वयं के परिभाषित इष्टतम मूल्य के साथ बफर सीमा बढ़ा सकें, उदाहरण के लिए नीचे दिए गए 50 एमबी:

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

हम इस सीमा को मोंगोडब कॉन्फिग फ़ाइल में नीचे के पैरामीटर द्वारा स्थायी रूप से सेट कर सकते हैं:

setParameter=internalQueryExecMaxBlockingSortBytes=309715200

उम्मीद है की यह मदद करेगा !!!

Note: यह कमांड केवल 3.0 संस्करण + के बाद समर्थन करता है


कॉन्फ़िगरेशन फ़ाइल में इस सीमा को स्थायी रूप से सेट करने का तरीका क्या है? मेरे पास एक 1 टीबी मेमोरी मशीन है जो मोंगो को समर्पित है और मैं इसे स्थायी रूप से क्रैंक करना चाहूंगा।
सामन्था एटकिंस

@SamanthaAtkins मैंने इसे कॉन्फिग फ़ाइल में स्थायी रूप से सेट करने के लिए उत्तर दिया है।
जेरी

@ जय जहां स्थायी रूप से रेल में स्थापित करने के लिए। पटरियों 5 / mongoid.yml?
प्रताप कुल

मुझे यह मिला। मेरे टर्मिनल पर साथ दौड़ें: mongod और मैन्युअल zocada.com/setting-mongodb-users-beginners-guide
Kul

24

अनुक्रमण के साथ हल किया गया

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

एक विरल सूचकांक का उपयोग न करने के लिए सुनिश्चित हो, यदि आप हर दस्तावेज पर छांटते हैं तो उन्हें नजरअंदाज कर दिया जाता है
चार्ली कोजा

15

यदि आप एक इंडेक्स बनाने से बचना चाहते हैं (जैसे आप डेटा का पता लगाने के लिए एक त्वरित और गंदा चेक चाहते हैं), तो आप डिस्क उपयोग के साथ एकत्रीकरण का उपयोग कर सकते हैं:

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

(यह पाइमोंगो में कैसे करना है, यह सुनिश्चित नहीं है, हालांकि)।


Pymongo में होगा db_handle.aggregate(pipe, allowDiskUse=True)। अधिक जानकारी के लिए यह प्रश्न देखें !
Genarito

3

इंडेक्स के लिए जावास्क्रिप्ट एपीआई सिंटैक्स:

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() } )
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.