इसे साफ करने के लिए एक नया उत्तर पोस्ट करना। मैंने परीक्षण किए और स्रोत कोड को फिर से पढ़ा और मुझे यकीन है कि जलन लेखन चिंता दस्तावेज़ीकरण में एक दुर्भाग्यपूर्ण वाक्य से आती है। जर्नलिंग सक्षम और j:true
. के साथ चिंता लिखें, लेखन टिकाऊ है, और डेटा हानि के लिए कोई रहस्यमय खिड़की नहीं है।
भले ही जर्नलिंग चालू हो, क्या अब भी MongoDB में लेखन खोने का मौका है?
हां, क्योंकि स्थायित्व व्यक्तिगत संचालन पर भी निर्भर करता है जो चिंता लिखता है।
<ब्लॉकक्वॉट>"डिफ़ॉल्ट रूप से, खोए हुए लेखन की सबसे बड़ी सीमा, यानी, जो जर्नल में नहीं बने हैं, वे पिछले 100 मिलीसेकंड में बने हैं।"
यह मैनेज जर्नलिंग से है, जो इंगित करता है कि पिछली बार जब जर्नल को डिस्क पर फ़्लश किया गया था, तब से किए गए लेखन को आप खो सकते हैं।
यह सही है। जर्नल को एक अलग थ्रेड द्वारा एसिंक्रोनस रूप से फ़्लश किया जाता है, इसलिए आप अंतिम फ्लश के बाद से सब कुछ खो सकते हैं।
<ब्लॉकक्वॉट>
यदि मैं अधिक स्थायित्व चाहता हूं, "मोंगॉड को अधिक बार पत्रिका के लिए प्रतिबद्ध करने के लिए, आप j:true
निर्दिष्ट कर सकते हैं . जब j:true
. के साथ एक राइट ऑपरेशन लंबित है, मोंगॉड कम कर देगा journalCommitInterval
निर्धारित मूल्य के एक तिहाई तक।"
इसने मुझे भी परेशान किया। इसका मतलब यह है:
जब आप j:true
. के साथ एक राइट ऑपरेशन भेजते हैं , यह डिस्क फ्लश को तुरंत ट्रिगर नहीं करता है, न कि नेटवर्क थ्रेड पर। यह समझ में आता है, क्योंकि एक ही मोंगॉड उदाहरण से बात करने वाले दर्जनों अनुप्रयोग हो सकते हैं। यदि प्रत्येक एप्लिकेशन जर्नलिंग का बहुत अधिक उपयोग करता है, तो डीबी बहुत धीमा होगा क्योंकि यह हर समय fsyncing है।
इसके बजाय, क्या होता है कि 'टिकाऊता धागा' सभी लंबित जर्नल कमिट्स को ले जाएगा और उन्हें डिस्क पर फ्लश कर देगा। धागा इस तरह कार्यान्वित किया जाता है (टिप्पणियां मेरी):
sleepmillis(oneThird); //dur.cpp, line 801
for( unsigned i = 1; i <= 2; i++ ) {
// break, if any j:true write is pending
if( commitJob._notify.nWaiting() )
break;
// or the number of bytes is greater than some threshold
if( commitJob.bytes() > UncommittedBytesLimit / 2 )
break;
// otherwise, sleep another third
sleepmillis(oneThird);
}
// fsync all pending writes
durThreadGroupCommit();
तो एक लंबित j:true
ऑपरेशन के कारण जर्नल प्रतिबद्ध थ्रेड सामान्य से पहले प्रतिबद्ध हो जाएगा, और यह जर्नल को सभी लंबित लेखन को प्रतिबद्ध करेगा, जिनमें वे भी शामिल हैं जिनके पास j:true
नहीं है सेट।
इस मामले में भी, ऐसा लगता है कि जर्नल को डिस्क पर फ्लश करना अतुल्यकालिक है, इसलिए अभी भी लिखने को खोने का एक मौका है। क्या मुझे इस बारे में कुछ याद आ रहा है कि कैसे गारंटी दी जाए कि लेखन खो नहीं गया है?
लिखना (या getLastError
कमांड) j:true
. के साथ जर्नलेड राइट कंसर्न ड्यूरेबिलिटी थ्रेड के सिंक होने की प्रतीक्षा करेगा , इसलिए डेटा हानि का कोई जोखिम नहीं है (जहाँ तक OS और हार्डवेयर इसकी गारंटी देते हैं)।
वाक्य "हालांकि, जर्नल कमिट्स के बीच एक विंडो होती है जब राइट ऑपरेशन पूरी तरह से टिकाऊ नहीं होता है" संभवतः जर्नलिंग सक्षम के साथ चलने वाले एक मोंगॉड को संदर्भित करता है जो एक ऐसे लेखन को स्वीकार करता है जो नहीं करता है j:true
का उपयोग करें चिंता लिखें। उस स्थिति में, पिछले जर्नल कमिटमेंट के बाद से लेखन के खो जाने की संभावना है।
मैंने इसके लिए एक डॉक्स बग रिपोर्ट दर्ज की है।