SQLite में परमाणु प्रतिबद्ध तंत्र

यह लेख sqlite.org के एक दिलचस्प लेख का आंशिक अनुवाद है जो SQLite में लेनदेन के कार्यान्वयन का विवरण देता है। वास्तव में, मैं शायद ही कभी SQLite के साथ काम करता हूं, लेकिन फिर भी मुझे यह पढ़ना बहुत पसंद है। इसलिए, यदि आप केवल अपने क्षितिज को विकसित करना चाहते हैं, तो यह पढ़ना दिलचस्प होगा। पहले दो खंड अनुवाद में शामिल नहीं हैं, क्योंकि वहाँ कुछ भी दिलचस्प नहीं है, और मैं उन्हें भरने के लिए बहुत आलसी हूं (पोस्ट पहले से ही बहुत बड़ा है)।

3.0 सिंगल फाइल कमेटी

हम उन चरणों की समीक्षा करके शुरू करते हैं जो SQLite एक परमाणु लेनदेन करने के लिए करता है जिसमें केवल एक डेटाबेस फ़ाइल शामिल होती है। फ़ाइल प्रारूप का विवरण जो डेटाबेस के भ्रष्टाचार से बचाने के लिए उपयोग किया जाता है और कई डेटाबेस के लिए उपयोग की जाने वाली तकनीकों को नीचे दिखाया जाएगा।

३.१ प्रारंभिक अवस्था


सिस्टम की स्थिति जब डेटाबेस से कनेक्शन सिर्फ उठाया गया है, सतही रूप से दाईं ओर की आकृति में दिखाया गया है। दाईं ओर दिखाई गई जानकारी ऊर्जा-स्वतंत्र माध्यम पर संग्रहीत है। प्रत्येक आयत एक सेक्टर है। नीला रंग इंगित करता है कि इस क्षेत्र में मूल डेटा है। बीच में ऑपरेटिंग सिस्टम का डिस्क कैश है। हमारे उदाहरण की शुरुआत में, कैश ठंडा है, इसे सफेद रंग में दिखाया गया है। आकृति के बाईं ओर प्रक्रिया के RAM की सामग्री है जो SQLite का उपयोग करता है। डेटाबेस कनेक्शन अभी खोला गया है और कोई जानकारी नहीं पढ़ी गई है।


3.2 रीड लॉक प्राप्त करना


इससे पहले कि SQLite रिकॉर्डिंग शुरू कर सके, उसे पहले यह पता लगाना होगा कि पहले से क्या है। यहां तक ​​कि अगर यह केवल नया डेटा सम्मिलित कर रहा है, तो उसे sqlite_master तालिका से स्कीमा को पढ़ने की आवश्यकता है ताकि वह जानता हो कि INSERT क्वेरी को कैसे पार्स किया जाए और यह समझें कि डेटा को विशेष रूप से कहाँ लिखना है।
पहला कदम डेटाबेस फ़ाइल पर एक साझा लॉक प्राप्त करना है। एक साझा लॉक एक ही समय में एक फ़ाइल से दो या अधिक कनेक्शनों को पढ़ने की अनुमति देता है। लेकिन इस प्रकार का अवरोधन अन्य कनेक्शनों को तब तक रिकॉर्ड करने से रोकता है जब तक इसे हटा नहीं दिया जाता। यह आवश्यक है, क्योंकि यदि एक ही समय में एक और कनेक्शन लिख रहा था, तो हम परिवर्तन के बाद कुछ अपरिवर्तित डेटा और डेटा के एक अन्य हिस्से को पढ़ सकते हैं। तब रिकॉर्ड को गैर-परमाणु माना जा सकता था।
ध्यान दें कि लॉक ओएस के डिस्क कैश पर स्थापित किया गया था, और डिस्क पर ही नहीं। फ़ाइल लॉक आमतौर पर सिस्टम के कर्नेल द्वारा नियंत्रित किए गए झंडे होते हैं। सिस्टम में कोई खराबी या पावर फेल होने पर वे रीसेट हो जाएंगे। वे भी आमतौर पर रीसेट हो जाते हैं जब एक प्रक्रिया जो ताला प्राप्त करती है मर जाती है।

3.3 डेटाबेस से जानकारी पढ़ना


लॉक प्राप्त होने के बाद, हम डेटाबेस फ़ाइल से पढ़ना शुरू कर सकते हैं। इस परिदृश्य में, हमारा मतलब है कि कैश अभी तक गर्म नहीं हुआ है, इसलिए जानकारी को पहले डेटा स्टोरेज डिवाइस से ऑपरेटिंग सिस्टम के कैश तक पढ़ा जाना चाहिए, और फिर इसे ओएस कैश से उपयोगकर्ता-स्थान पर ले जाया जा सकता है। बाद के रीडिंग में, सभी या कुछ जानकारी पहले से ही कैश में होगी, ताकि इसे केवल उपयोगकर्ता स्थान पर भेजना होगा।
आमतौर पर पृष्ठों का केवल एक छोटा सा हिस्सा डेटाबेस फ़ाइल से पढ़ा जाएगा। हमारे उदाहरण में, हम देखते हैं कि आठ पृष्ठों में से केवल तीन ही पढ़े गए थे। एक विशिष्ट एप्लिकेशन में, डेटाबेस में हजारों पृष्ठ होंगे और क्वेरी उनमें से बहुत कम प्रतिशत को प्रभावित करेगी।

3.4 "बैकअप" लॉक प्राप्त करना


डेटाबेस में कोई भी बदलाव करने से पहले, SQLite को पहले डेटाबेस फाइल पर लगभग "आरक्षित" लॉक मिलता है (लगभग। - - यह मेरे लिए हुआ सबसे सहनीय अनुवाद है)। ऐसा लॉक एक संयुक्त के समान है जिसमें यह डेटाबेस फ़ाइल से अन्य प्रक्रियाओं को भी पढ़ने की अनुमति देता है। एक बैकअप लॉक कई साझा लॉक के साथ सह-अस्तित्व में आ सकता है। हालाँकि, प्रति फ़ाइल केवल एक बैकअप लॉक एक समय में मौजूद हो सकता है। इस प्रकार, एक समय में केवल एक प्रक्रिया ही डेटाबेस को लिख सकती है।
बैकअप लॉक का विचार यह है कि यह निकट भविष्य में एक फ़ाइल पर लिखना शुरू करने की प्रक्रिया के इरादे के बारे में बात करता है, लेकिन अभी तक ऐसा करना शुरू नहीं हुआ है। और, चूंकि परिवर्तन अभी तक लिखे जाने शुरू नहीं हुए हैं, अन्य प्रक्रियाएं डेटाबेस से पढ़ना जारी रख सकती हैं। लेकिन कोई भी प्रक्रिया रिकॉर्डिंग को आरंभ नहीं कर सकती है जबकि ताला जीवित है।

3.5 रोलबैक लॉग बनाना


इससे पहले कि आप डेटाबेस फ़ाइल में लिखना शुरू करें, SQLite पहले परिवर्तनों को वापस रोल करने के लिए एक अलग लॉग बनाता है, और इसे मूल डेटाबेस पृष्ठों को लिखता है जो बदल जाएगा। रोलबैक लॉग में लेन-देन से पहले डेटाबेस को उसकी मूल स्थिति में वापस करने के लिए सभी आवश्यक जानकारी होती है।
रोलबैक लॉग में एक छोटा हेडर होता है (आरेख पर हरे रंग में दिखाया गया है) जिसमें डेटाबेस फ़ाइल का आकार अपनी मूल स्थिति में होता है। इसलिए, यदि परिवर्तन के बाद डेटाबेस फ़ाइल आकार में बढ़ती है, तो हम अभी भी इसके मूल आकार को जान पाएंगे। लॉग में प्रत्येक पृष्ठ के बगल में पृष्ठ संख्या संग्रहीत है।
जब एक नई फ़ाइल बनाई जाती है, तो अधिकांश ऑपरेटिंग सिस्टम (विंडोज, लिनक्स, मैक ओएस एक्स) वास्तव में डिस्क पर कुछ भी नहीं लिखेंगे। एक नई फ़ाइल केवल ऑपरेटिंग सिस्टम के कैश में बनाई गई है। फ़ाइल को ड्राइव पर तब तक नहीं बनाया जाता है जब तक ऑपरेटिंग सिस्टम को इसके लिए सही समय नहीं मिल जाता है। यह उपयोगकर्ता के लिए उपस्थिति बनाता है कि ड्राइव पर इनपुट / आउटपुट ऑपरेशन संभव से बहुत तेज हैं। हमने दाईं ओर आरेख में इस प्रक्रिया को दर्शाया है, जिसमें दिखाया गया है कि रोलबैक लॉग केवल डिस्क कैश में दिखाई देता है, लेकिन डिस्क पर ही नहीं।

उपयोगकर्ता स्थान में 3.6 डेटाबेस पृष्ठ बदलना


मूल सामग्री को रोलबैक लॉग में सहेजे जाने के बाद, पृष्ठों को उपयोगकर्ता मेमोरी में बदला जा सकता है। डेटाबेस के प्रत्येक कनेक्शन की उपयोगकर्ता स्थान की अपनी निजी प्रति होती है, जिससे उपयोगकर्ता स्थान में किए गए परिवर्तन केवल इस कनेक्शन के लिए दिखाई देते हैं। अन्य कनेक्शन अभी भी डिस्क कैश जानकारी देखते हैं जो अभी तक नहीं बदला गया है। इसलिए, भले ही एक प्रक्रिया डेटाबेस में डेटा बदलने में शामिल है, अन्य प्रक्रियाएं मूल सामग्री की अपनी प्रतियां पढ़ना जारी रख सकती हैं।

3.7 ड्राइव करने के लिए रोलबैक लॉग को रीसेट करें


अगला कदम कैश से एनर्जी-इंडिपेंडेंट मेमोरी में रोलबैक जर्नल को रीसेट करना है। जैसा कि हम बाद में देखेंगे, यह एक बहुत ही महत्वपूर्ण कदम है, जो हमें बिजली की विफलता के मामले में डेटा सुरक्षा की गारंटी देता है। इस कदम के लिए भी बहुत समय की आवश्यकता होती है, क्योंकि ऊर्जा-स्वतंत्र मेमोरी में लिखना आमतौर पर एक धीमा ऑपरेशन होता है।
यह कदम आमतौर पर लॉग को डिस्क को डंप करने की तुलना में अधिक जटिल है। अधिकांश प्लेटफार्मों पर, आपको दो फ्लश (या fsync) करने की आवश्यकता होती है। पहले फ्लश लॉग की मुख्य सामग्री लिखते हैं। फिर लॉग के हेडर को लॉग में पृष्ठों की संख्या को प्रतिबिंबित करने के लिए बदल दिया जाता है। उसके बाद, हेडर को डिस्क में फ्लश किया जाता है। हमें इसकी आवश्यकता क्यों है, इसकी व्याख्या नीचे दी गई है।

3.8 विशेष लॉक प्राप्त करें


डेटाबेस फ़ाइल में परिवर्तन करने से पहले, हमें पहले उस पर एक विशेष लॉक प्राप्त करना होगा। इस तरह के लॉक को प्राप्त करने में दो चरण होते हैं। सबसे पहले, SQLite एक लंबित ताला प्राप्त करता है। फिर इस लॉक को अनन्य में स्थानांतरित किया जाता है।
"लंबित लॉक" अन्य प्रक्रियाओं की अनुमति देता है जिनके पास फ़ाइल से रीडिंग जारी रखने के लिए फ़ाइल पर पहले से ही एक साझा लॉक है। लेकिन यह अन्य प्रक्रियाओं को नए साझा ताले प्राप्त करने से रोकता है। यह आवश्यक है ताकि बड़े और लगातार पढ़ी गई अनुरोधों की संख्या के कारण रिकॉर्डिंग सही न होने पर स्थिति बदल न जाए। प्रत्येक प्रक्रिया को पढ़ने से पहले एक साझा लॉक मिलता है, जिसके बाद वह लॉक को पढ़ता है और रीसेट करता है। जब कई प्रक्रियाएं होती हैं जिन्हें लगातार पढ़ने की आवश्यकता होती है, तो ऐसी स्थिति उत्पन्न हो सकती है जहां प्रत्येक नई प्रक्रिया को अपना लॉक मिल जाता है, इससे पहले कि कोई भी अपना लॉक जारी करता है। इस प्रकार, कभी भी ऐसा क्षण नहीं होगा जब फ़ाइल पर एक भी साझा लॉक न हो, और तदनुसार कोई अनन्य लॉक प्राप्त करने का कोई तरीका नहीं होगा। एक समान स्थिति होने की संभावना को रोकने के लिए "ऑन होल्ड" लॉक की आवश्यकता होती है, फ़ाइल पर नए संयुक्त ताले प्राप्त होने से रोकते हैं, लेकिन मौजूदा एक को जारी रखने की अनुमति देते हैं। जब सभी साझा ताले जारी किए जाते हैं, तो लंबित लॉक को अनन्य लॉक स्थिति में स्थानांतरित किया जा सकता है।

3.9 डेटाबेस फ़ाइल में डेटा लिखना


जब एक विशेष लॉक प्राप्त होता है, तो हम यह सुनिश्चित कर सकते हैं कि कोई और प्रक्रिया इस फ़ाइल को नहीं लिखती है और इसमें परिवर्तन किए जा सकते हैं। आमतौर पर, ये परिवर्तन केवल OS के डिस्क कैश तक पहुंचते हैं और डिस्क में ही नहीं प्रवाहित होते हैं।

3.10 ड्राइव पर डेटा रीसेट करें


अब आपको फ्लश कॉल करने की आवश्यकता है सुनिश्चित करें कि डेटाबेस में सभी परिवर्तन ऊर्जा-स्वतंत्र मेमोरी में लिखे गए हैं। यह डेटा के लिए एक संभावित संभावित अंधकार से बचने के लिए एक महत्वपूर्ण कदम है। डिस्क और फ्लैश मेमोरी की सुस्ती के कारण, यह कदम, रोलबैक लॉग (धारा 3.7) की रिकॉर्डिंग के साथ, SQLite में लेनदेन करने में बिताए गए समय का सबसे बड़ा हिस्सा लेता है।

3.11 रोलबैक लॉग हटाएं


डिस्क में परिवर्तन सहेजे जाने के बाद, हमें रोलबैक लॉग को हटाना होगा। यह ठीक क्षण है जब हम कह सकते हैं कि प्रतिबद्ध सफलतापूर्वक पूरा हुआ। यदि बिजली की विफलता या किसी प्रकार की प्रणाली की विफलता विलोपन से पहले होती है, तो डेटाबेस प्रतिबद्ध से पहले - अपनी पिछली स्थिति में पुनर्स्थापित करेगा। यदि रोलबैक लॉग को हटाने के बाद बिजली की विफलता होती है, तो प्रतिबद्ध होगा। इस प्रकार, SQLite में एक कमिट की सफलता अंततः इस बात पर निर्भर करती है कि रोलबैक के लिए लॉग फाइल को डिलीट किया गया था या नहीं।
किसी फ़ाइल को हटाना वास्तव में एक परमाणु ऑपरेशन नहीं है, लेकिन यह उपयोगकर्ता प्रक्रिया के दृष्टिकोण से ऐसा दिखता है। एक प्रक्रिया हमेशा ऑपरेटिंग सिस्टम से पूछ सकती है: "क्या यह फ़ाइल मौजूद है?" और यह प्रतिक्रिया में "हाँ" या "नहीं" प्राप्त करेगा। ट्रांजेक्शन कमिट के दौरान होने वाली बिजली की विफलता के बाद, SQLite ऑपरेटिंग सिस्टम से पूछेगा कि क्या कोई लेन-देन रोलबैक लॉग फ़ाइल मौजूद है। यदि ऐसा है, तो लेन-देन पूरा नहीं हुआ है और इसे वापस ले लिया जाएगा। यदि उत्तर नहीं था, तो लेनदेन सफलतापूर्वक पूरा हो गया था।
अपूर्ण लेनदेन का अस्तित्व इस बात पर निर्भर करता है कि क्या रोलबैक लॉग फ़ाइल मौजूद है, और इसका विलोपन अंतिम उपयोगकर्ता के दृष्टिकोण से एक परमाणु संचालन की तरह दिखता है। इसलिए, लेनदेन एक परमाणु संचालन की तरह दिखता है।
एक फ़ाइल को हटाना कई प्रणालियों पर एक महंगा ऑपरेशन है। अनुकूलन के रूप में, SQLite लंबाई में शून्य बाइट्स को ट्रिम कर सकता है, या शीर्ष लेख को शून्य से भर सकता है। किसी भी मामले में, परिणामस्वरूप, लॉग फ़ाइल को रोलबैक के लिए पढ़ना संभव नहीं होगा और लेनदेन प्रतिबद्ध होगा। किसी फ़ाइल को लंबाई में शून्य करने के साथ-साथ हटाना, उपयोगकर्ता प्रक्रिया के दृष्टिकोण से परमाणु संचालन माना जाता है। शून्य के साथ लॉग हेडर को अधिलेखित करना परमाणु नहीं है, लेकिन यदि हेडर का कोई हिस्सा क्षतिग्रस्त है, तो लॉग का उपयोग रोलबैक के लिए नहीं किया जाएगा। इस प्रकार, हम यह कह सकते हैं कि रोलबैक लॉग के हेडर अमान्य हो जाने पर यह कमिट हुई। आमतौर पर ऐसा तब होता है जब हेडर का केवल पहला बाइट रीसेट होता है।

3.12 अनलॉक


प्रतिबद्ध का अंतिम चरण अनन्य लॉक को निकालना है ताकि बाकी प्रक्रियाओं में फिर से डेटाबेस तक पहुंच हो।
दाईं ओर की आकृति में, हमने दिखाया कि अनलॉक करने के बाद उपयोगकर्ता मेमोरी में जो जानकारी थी, वह साफ हो गई। यह वास्तव में SQLite के पुराने संस्करणों में मामला था। लेकिन SQLite के नए संस्करणों में, जानकारी को अगले लेनदेन के लिए आवश्यक होने पर उपयोगकर्ता स्थान में संग्रहीत किया जाता है। ऐसे डेटा का उपयोग करना सस्ता है जो पहले से ही मेमोरी में है, इसे डिस्क कैश से पुनर्प्राप्त करने या डिस्क से ही पढ़ने के बजाय। इस डेटा का उपयोग करने से पहले, हमें साझा लॉक को फिर से प्राप्त करने की आवश्यकता है, और हमें यह भी सुनिश्चित करने की आवश्यकता है कि किसी भी प्रक्रिया ने डेटाबेस की स्थिति को तब तक नहीं बदला है जब तक हमारे पास लॉक नहीं था। डेटाबेस फ़ाइल में पहले पृष्ठ पर एक काउंटर है जो हर परिवर्तन के साथ वेतन वृद्धि करता है। हम पता लगा सकते हैं कि क्या डेटाबेस की स्थिति इस काउंटर की जाँच करके बदल गई है। यदि डेटाबेस में परिवर्तन किए गए थे, तो उपयोगकर्ता कैश को हटा दिया जाना चाहिए और ओवरहीट किया जाना चाहिए। लेकिन अधिक बार ऐसा होता है कि कोई बदलाव नहीं किया गया और उपयोगकर्ता कैश का उपयोग आगे किया जा सकता है, जो प्रदर्शन में अच्छी वृद्धि देता है।

4.0 रोलबैक

परमाणु प्रतिबद्धता तात्कालिक होनी चाहिए। लेकिन उन सभी कार्यों को जो ऊपर वर्णित थे, स्पष्ट रूप से पूरा करने के लिए कुछ समय लेते हैं। मान लें कि ऊपर वर्णित कमेटी प्रक्रिया के बीच में कंप्यूटर की शक्ति बंद कर दी गई थी। तात्कालिक परिवर्तनों के भ्रम को बनाए रखने के लिए, हमें उन सभी आंशिक परिवर्तनों को वापस लेना चाहिए जो किए गए थे और डेटाबेस को उसकी मूल स्थिति में पुनर्स्थापित कर रहे थे।

4.1 जब कुछ गलत होता है


मान लें कि डिस्क में परिवर्तन लिखे जाने पर चरण 3.10 में बिजली की विफलता हुई। जब बिजली बहाल हो जाती है, तो स्थिति कुछ उसी तरह होगी जो आंकड़े में दाईं ओर दिखाई गई है। हमने डेटाबेस फ़ाइल में तीन पृष्ठों को बदलने की कोशिश की, लेकिन उनमें से केवल डिस्क पर सफलतापूर्वक लिखा गया था। अन्य पृष्ठ आंशिक रूप से दर्ज किया गया था, और तीसरा पूरी तरह से अपनी मूल स्थिति में रहा।
रोलबैक लॉग बिजली बहाल होने के बाद डिस्क पर पूरी तरह से होगा। यह प्रमुख बिंदु है। चरण ३. is में फ्लश की आवश्यकता का कारण पूरी तरह से निश्चित है कि डेटाबेस फ़ाइल में किसी भी परिवर्तन से पहले संपूर्ण रोलबैक लॉग को पूरी तरह से ऊर्जा-स्वतंत्र मेमोरी में सहेजा जाता है।

4.2 हॉट रोलबैक लॉग


जब एक SQLite प्रक्रिया पहली बार डेटाबेस फाइल को एक्सेस करने की कोशिश करती है, तो उसे पहले इस पर एक साझा लॉक मिलता है, जैसा कि खंड 3.2 में वर्णित है। लेकिन फिर उसे पता चलता है कि रोलबैक लॉग है। फिर SQLite यह देखने के लिए जांचता है कि क्या यह लॉग "हॉट रोलबैक लॉग" है। हॉट लॉग एक रोलबैक लॉग है जिसे डेटाबेस में लागू किया जाना चाहिए ताकि इसे अक्षुण्ण अवस्था में पुनर्स्थापित किया जा सके। एक गर्म लॉग केवल तब मौजूद होता है जब लेनदेन प्रक्रिया के कुछ चरणों में कुछ प्रक्रिया पहले की गई थी और किसी कारण से, उस समय गिर गई थी।
यदि सभी शर्तें सत्य हैं, तो रोलबैक लॉग "हॉट" है:

हॉट लॉग की उपस्थिति एक संकेत है कि पिछली प्रक्रिया ने लेनदेन करने की कोशिश की, लेकिन किसी कारण से विफल रही। हॉट लॉग का अर्थ है कि डेटाबेस फ़ाइल असंगत स्थिति में है और उपयोग करने से पहले पुनर्स्थापित की जानी चाहिए।

4.3 डेटाबेस फ़ाइल पर एक विशेष लॉक प्राप्त करना


हॉट लॉग के साथ काम करने से पहले पहला कदम डेटाबेस फ़ाइल पर एक विशेष लॉक प्राप्त करना है। यह एक ऐसी स्थिति को रोक देगा जहां दो या अधिक प्रक्रियाएं एक ही समय में एक ही हॉट लॉग को लागू करने की कोशिश कर रही हैं।

4.4 रोलबैक अधूरा परिवर्तन


जैसे ही प्रक्रिया एक विशेष ताला प्राप्त करती है, इसे डेटाबेस फ़ाइल में लिखने की अनुमति दी जाती है। फिर वह रोलबैक लॉग से पृष्ठों की मूल सामग्री को पढ़ने और डेटाबेस में वापस लिखने की कोशिश करता है। याद रखें कि लॉग के शीर्षलेख में डेटाबेस फ़ाइल का आकार अपनी मूल स्थिति में है? SQLite इस जानकारी का उपयोग उन मामलों में डेटाबेस फ़ाइल को उसके मूल आकार में ट्रिम करने के लिए करता है, जहां इस फ़ाइल की वृद्धि के कारण अधूरा लेनदेन हुआ। इस चरण के बाद, डेटाबेस एक ही आकार का होना चाहिए और अपूर्ण लेनदेन से पहले बिल्कुल उसी डेटा को शामिल करना चाहिए।

4.5 हॉट लॉग हटाना


डेटाबेस फ़ाइल में पूरे लॉग को लागू करने के बाद (और एक अन्य बिजली नुकसान के मामले में डिस्क में भी प्रवाहित किया जाता है), इसे (लॉग) को हटाया जा सकता है।
खंड 3.11 के रूप में, लॉग फ़ाइल को लंबाई में शून्य बाइट्स के लिए छोटा किया जा सकता है, या इसके हेडर को शून्य के साथ ओवरराइट किया जा सकता है। किसी भी मामले में, इस कदम के बाद लॉग अब "गर्म" नहीं है।

4.6 जारी रखें जैसे कि कोई लेनदेन प्रगति पर नहीं था


अंतिम पुनर्प्राप्ति चरण अनन्य लॉक को संयुक्त में बदलना है। जब ऐसा होता है, डेटाबेस एक स्थिति में होगा जैसे कि लेन-देन वापस नहीं किया गया था। चूंकि यह पूरी पुनर्प्राप्ति प्रक्रिया उपयोगकर्ता के लिए स्वचालित रूप से और पारदर्शी रूप से होती है, ऐसा लगता है जैसे कोई पुनर्प्राप्ति नहीं हुई है।

5.0 कई फाइलों के लिए प्रतिबद्ध

SQLite आपको ATTACH DATABASE का उपयोग करके एक साथ एक ही कनेक्शन से दो या अधिक डेटाबेस से बात करने की अनुमति देता है। जब कई डेटाबेस फाइलें एक ही लेनदेन में बदल जाती हैं, तो सभी फाइलें परमाणु रूप से अपडेट की जाती हैं। दूसरे शब्दों में, या तो उन सभी को अपडेट किया गया है, या उनमें से कोई भी अपडेट नहीं किया जाएगा। कई फाइलों में परमाणु अपडेट हासिल करना कुछ हद तक मुश्किल है। यह खंड उन सभी जादू का वर्णन करेगा जो इसके पीछे निहित हैं।

5.1 प्रत्येक डेटाबेस के लिए अलग रोलबैक लॉग


जब कोई लेनदेन कई डेटाबेस फ़ाइलों को प्रभावित करता है, तो इनमें से प्रत्येक फ़ाइल का अपना रोलबैक लॉग होता है, और प्रत्येक फ़ाइल के लिए लॉक अलग से प्राप्त होता है। दाईं ओर का आंकड़ा उस स्थिति को दिखाता है जब एक ही लेन-देन के भीतर तीन अलग-अलग डेटाबेस फ़ाइलों को बदला गया था। इस चरण की स्थिति खंड 3.6 से एक एकल फ़ाइल पर एक सामान्य लेनदेन के समान है। बैकअप लॉक प्रत्येक डेटाबेस फ़ाइल पर लटका दिया जाता है। प्रत्येक डेटाबेस के लिए, अब बदले जाने वाले पृष्ठों की मूल सामग्री को उचित रोलबैक लॉग्स में लिखा जाएगा, लेकिन ये लॉग अभी तक डिस्क में नहीं डाले गए हैं। डेटाबेस फ़ाइलों को अभी तक नहीं बदला गया है, लेकिन परिवर्तन पहले से ही प्रक्रिया की उपयोगकर्ता मेमोरी में हैं।
संक्षिप्तता के लिए, इस खंड में चित्र अन्य अनुभागों के सापेक्ष सरल किए गए हैं। नीला रंग अभी भी मूल जानकारी का मतलब है, और गुलाबी - नया। लेकिन डेटाबेस फ़ाइलों के रोलबैक लॉग में अलग-अलग पृष्ठ नहीं दिखाए गए हैं, और हम यह नहीं दिखाते हैं कि डिस्क पर पहले से ही क्या जानकारी है, और सिस्टम कैश में और क्या है। फिर भी, ये सभी कारक अभी भी एक बहु-फ़ाइल लेनदेन में मौजूद हैं, लेकिन वे आरेखों पर बहुत अधिक जगह लेंगे और हमें बहुत उपयोगी जानकारी नहीं देंगे, इसलिए वे यहां छोड़ दिए गए हैं।

5.2 मास्टर लॉग फ़ाइल

एक बहु-फ़ाइल लेनदेन में अगला कदम एक मास्टर लॉग बनाना है। मास्टर लॉग का नाम मूल डेटाबेस फ़ाइल के नाम के समान है (जिस पर कनेक्शन खोला गया था) फॉर्म की एक अतिरिक्त लाइन के साथ "-mjHHHHHHHH" ("मास्टर जर्नल" से "mj"), जहां HHHHHHH यादृच्छिक 32-बिट मान है जो कि के लिए उत्पन्न होता है प्रत्येक नए मास्टर लॉग।
(मास्टर लॉग फ़ाइल का नाम उत्पन्न करने के लिए यह एल्गोरिथ्म SQLite 3.5.0 के कार्यान्वयन का एक विवरण है। यह किसी भी तरह से विनिर्देशों में निर्दिष्ट नहीं है और किसी भी नए संस्करण में बदला जा सकता है)
रोलबैक लॉग के विपरीत, मास्टर लॉग में डेटाबेस से पृष्ठों की कोई मूल सामग्री नहीं होती है। इसके बजाय, इसमें लेन-देन में भाग लेने वाले प्रत्येक डेटाबेस के लिए रोलबैक लॉग फ़ाइलों के लिए पूर्ण पथ शामिल हैं।
मास्टर लॉग संकलित किए जाने के बाद, इसकी सामग्री डिस्क में प्रवाहित हो जाती है। यूनिक्स प्रणालियों पर, मास्टर लॉग डायरेक्टरी भी यह सुनिश्चित करने के लिए रीसेट की जाती है कि पावर विफलता के बाद मास्टर लॉग इस निर्देशिका में दिखाई देता है।

5.3 अद्यतन रोलबैक लॉग हेडर


अगला कदम प्रत्येक रोलबैक लॉग के हेडर में मास्टर लॉग फ़ाइल के लिए पूर्ण पथ लिखना है। रोलबैक लॉग फ़ाइलों में मास्टर लॉग फ़ाइल के नाम के तहत जगह अग्रिम में आवंटित की गई थी जब वे बनाए गए थे।
प्रत्येक रोलबैक लॉग की सामग्री को उसके हेडर में मास्टर लॉग का नाम लिखने से पहले और बाद में डिस्क में फ्लश किया जाता है। यह महत्वपूर्ण है कि हम सिर्फ दो डेटा डंप करें। सौभाग्य से, दूसरा फ्लश आमतौर पर सस्ती है, क्योंकि आमतौर पर लॉग फ़ाइल का केवल एक पृष्ठ बदला जाएगा।

5.4 डेटाबेस फ़ाइलों को अद्यतन करना


चूंकि रोलबैक लॉग फ़ाइलों को डिस्क में फ्लश किया गया था, हम डेटाबेस फ़ाइलों को अपडेट करने के लिए आगे बढ़ सकते हैं। हमें सभी फ़ाइलों पर अनन्य ताले प्राप्त करने की आवश्यकता है जिसमें हम परिवर्तन लिखने जा रहे हैं। परिवर्तनों को दर्ज किए जाने के बाद, आपको उन्हें डिस्क में फ्लश करने की आवश्यकता होगी।
यह चरण एकल-फ़ाइल प्रतिबद्ध से अनुभाग 3.8, 3.9 और 3.10 को दर्शाता है।

5.5 मास्टर लॉग हटाएं


अगला कदम मास्टर लॉग फ़ाइल को हटाना है। इस बिंदु पर, लेनदेन को पूरा माना जा सकता है। यह चरण एकल-फ़ाइल प्रतिबद्ध से खंड 3.11 को दर्शाता है, जहां रोलबैक लॉग को हटा दिया जाता है।
यदि इस समय बिजली की विफलता या किसी प्रकार की सिस्टम विफलता होती है, तो सिस्टम पुनर्प्राप्ति के बाद भी लेनदेन को अस्वीकार नहीं किया जाएगा, भले ही रोलबैक लॉग अभी भी जीवित हों। उनके हेडर में मास्टर लॉग फ़ाइल का नाम होता है, जिसका अर्थ है कि वे लागू नहीं होंगे यदि मास्टर लॉग स्वयं मौजूद नहीं है।

5.6 क्लियरिंग रोलबैक लॉग


अंतिम चरण रोलबैक लॉग में से प्रत्येक को हटाने और डेटाबेस फ़ाइलों में अनन्य ताले रीसेट करने के लिए होगा ताकि अन्य प्रक्रियाएं हमारे द्वारा किए गए परिवर्तनों को देख सकें।
इस बिंदु पर, लेनदेन को पहले से ही पूरा माना जाता है, इसलिए लॉग को हटाने के लिए लिया गया समय इतना महत्वपूर्ण नहीं है। वर्तमान कार्यान्वयन में, सभी लॉग को एक-एक करके डिलीट किया जाता है और साथ ही संबंधित डेटाबेस फ़ाइलों से ताले को हटा दिया जाता है - पहला पहला लॉग हटा दिया जाता है, और संबंधित लॉक को छोड़ दिया जाता है, फिर दूसरा लॉग और लॉक, और इसी तरह। लेकिन भविष्य में हम संभवतः इस व्यवहार को एक में बदल देंगे जिसमें पहले सभी लॉग हटा दिए जाएंगे, और फिर सभी ताले हटा दिए जाएंगे। मुख्य बात यह है कि ताले हटाने से पहले ताले की रिहाई होती है, और इसके बाद नहीं।

6.0 प्रतिबद्ध प्रक्रिया का अतिरिक्त विवरण

धारा 3.0 SQLite में परमाणु प्रतिबद्ध कैसे होता है, का अवलोकन प्रदान करता है, लेकिन कुछ महत्वपूर्ण विवरण छोड़ देता है। निम्नलिखित अनुभागों में, हम इन अंतरालों को भरने की कोशिश करेंगे।

6.1। संपूर्ण डिस्क क्षेत्र हमेशा लॉग इन होते हैं।

जब मूल डेटा को रोलबैक लॉग में लिखा जाता है, तो SQLite हमेशा पूर्ण सेक्टर लिखता है, भले ही पृष्ठ का आकार सेक्टर आकार से छोटा हो। ऐसा हुआ कि SQL आकार को 512 बाइट्स के रूप में सेक्टर आकार में हार्डकोड किया गया था, और चूंकि न्यूनतम पृष्ठ आकार भी 512 बाइट्स है, यह कभी भी समस्या नहीं रही है। लेकिन SQLite संस्करण 3.3.14 से शुरू होकर यह बड़े क्षेत्रों के साथ काम कर सकता है। इसलिए, इस संस्करण से शुरू करते हुए, जब किसी पृष्ठ को रोलबैक लॉग में लिखा जाता है, तो डिस्क पर उसी क्षेत्र में आने वाले एक अन्य पृष्ठ को भी इसके साथ लिखा जा सकता है।
सेक्टर रिकॉर्डिंग के दौरान ऊर्जा के अचानक नुकसान के साथ परिदृश्य को रोकने के लिए सही क्षेत्र में सभी पृष्ठों को गिरवी रखना महत्वपूर्ण है। मान लीजिए कि पेज 1, 2, 3 और 4 सभी सेक्टर 1 में संग्रहीत हैं, और उस पेज 2 को संशोधित किया गया है। पेज 2 में परिवर्तन लिखने के लिए, फ़ाइल सिस्टम को पेज 1, 3 और 4 की सामग्री को फिर से लिखना होगा, क्योंकि यह पूरे सेक्टर पर काम करता है। यदि यह रिकॉर्डिंग ऑपरेशन ऊर्जा की हानि से बाधित है, तो पेज 1, 3 या 4 में से कोई भी गलत डेटा के साथ रह सकता है। इसलिए, इस परिदृश्य से बचने के लिए, आपको रोलबैक लॉग में इन सभी पृष्ठों को सहेजने की आवश्यकता है।

6.2 लॉग में खराब डेटा के साथ क्या करना है

जब डेटा को रोलबैक लॉग फ़ाइल में लिखा जाता है, तो SQLite यह मान लेता है कि फ़ाइल पहले "यादृच्छिक" डेटा (डेटा जो फ़ाइल के आकार में वृद्धि होने तक इस स्थान पर हुआ करती थी और डिस्क के इस हिस्से को इसके द्वारा कैप्चर किया गया था) से भरा है, और उसके बाद ही सही डेटा इसे बदलता है। दूसरे शब्दों में, SQLite मानता है कि फ़ाइल का आकार पहले बढ़ता है (इसके लिए स्थान आवंटित किया गया है (क्षमा करें, इसके तहत आवंटित), और उसके बाद केवल डेटा को लिखा जाता है। यदि फ़ाइल का आकार बदलने के बाद बिजली की विफलता होती है, लेकिन डेटा लिखने से पहले, रोलबैक लॉग में खराब डेटा होगा। बिजली की आपूर्ति बहाल होने के बाद, एक अन्य SQLite प्रक्रिया में एक रोलबैक लॉग फ़ाइल दिखाई देगी जिसमें कचरा डेटा होता है और इसके आधार पर वापस रोल करने का प्रयास करेगा, इस प्रकार डेटाबेस दूषित हो जाएगा।
SQLite इस समस्या से निपटने के लिए दो तकनीकों का उपयोग करता है। सबसे पहले, SQLite रोलबैक लॉग के हेडर में पृष्ठों की संख्या लिखता है। यह संख्या पहले शून्य के रूप में लिखी गई है। इसलिए अपूर्ण लॉग को रोलबैक करने के प्रयास के दौरान, प्रक्रिया यह देखेगी कि लॉग में एक भी पृष्ठ नहीं है और रोलबैक बस नहीं होगा। कमिट करने से पहले, रोलबैक लॉग को डिस्क में फ्लश कर दिया जाता है, और उसके बाद ही यह वांछित संख्या से पृष्ठों की संख्या को सही करता है। लॉग हेडर हमेशा डिस्क के एक अलग सेक्टर को लिखा जाता है, यह सुनिश्चित करने के लिए कि बिजली की विफलता की स्थिति में ओवरराइटिंग इन पृष्ठों को नुकसान नहीं पहुंचाती है। ध्यान दें कि लॉग को दो बार डिस्क में प्रवाहित किया जाता है: पहले पृष्ठों की सामग्री लिखने के लिए, और फिर शीर्ष लेख में पृष्ठों की संख्या जोड़ने के लिए।
पिछले पैराग्राफ में ध्वज PRAGMA synchronous=FULL; साथ SQLite के व्यवहार का वर्णन है PRAGMA synchronous=FULL;
डिफ़ॉल्ट रूप से, यह ध्वज FULL सेट है; यदि यह NORMAL सेट है, तो SQLite पृष्ठों की संख्या रिकॉर्ड करने के बाद केवल एक बार लॉग को रीसेट करेगा। यह डेटा भ्रष्टाचार के जोखिम को बढ़ाता है, क्योंकि ऐसा हो सकता है कि डेटाबेस पृष्ठों से पहले पृष्ठों की संख्या लिखी गई हो। हालाँकि, पेज डेटा पहले लिखने के लिए भेजा गया था, लेकिन SQLite मानता है कि फ़ाइल सिस्टम लिखने के काम के क्रम को पुनर्व्यवस्थित कर सकता है और, तदनुसार, पहले स्थान पर पृष्ठों की संख्या रिकॉर्ड करता है। इसके खिलाफ एक अन्य बचाव के रूप में, SQLite रोलबैक लॉग में प्रत्येक पृष्ठ के लिए 32-बिट हस्ताक्षर (हैश) का उपयोग करता है। यदि यह पता चला है कि लॉग में कोई पृष्ठ उसके हस्ताक्षर से मेल नहीं खाता है, तो रोलबैक रद्द कर दिया जाता है।
यदि synchronous ध्वज FULL सेट है, तो लॉग में हस्ताक्षर वैकल्पिक हैं। हमें केवल उनकी आवश्यकता है यदि यह ध्वज NORMAL । हालांकि, वे कभी चोट नहीं पहुंचाएंगे, इसलिए हम उन्हें सभी मोड में लॉग में शामिल करते हैं।

6.3 प्रतिबद्ध के दौरान कैश ओवरफ्लो

खंड 3.0 में प्रतिबद्ध प्रक्रिया मानती है कि सभी परिवर्तन करने से पहले स्मृति में फिट हो जाएंगे। यह सबसे अधिक संभावना वाला मामला है। लेकिन कभी-कभी ऐसा होता है कि परिवर्तनों का एक सेट उपयोगकर्ता प्रक्रिया के लिए आवंटित मेमोरी को ओवरफ्लो करता है। ऐसे मामलों में, लेनदेन पूरा होने से पहले कैश को डेटाबेस में भेजा जाना चाहिए।
भेजने की बहुत शुरुआत में, डेटाबेस राज्य में है जैसा कि खंड 3.6 में दिखाया गया है। मूल डेटा रोलबैक लॉग में सहेजा गया था और उपयोगकर्ता मेमोरी में परिवर्तन हैं। कैश भेजने के लिए, SQLite 3.7, 3.8 और 3.9 चरणों से गुजरता है। लॉग को डिस्क में फ्लश किया गया था, डेटाबेस फ़ाइल पर एक विशेष लॉक प्राप्त किया गया था, और सभी परिवर्तन दर्ज किए गए थे। उसके बाद, अंत में लॉग में एक और हेडर जोड़ा जाता है, और हम चरण 3.6 पर लौट आते हैं। जब लेन-देन पूरा हो जाता है, या यदि लिखने के लिए अधिक डेटा है, तो हम चरण ३. is पर लौट आएंगे, फिर ३.९। (चरण 3.8, हमें अब इसकी आवश्यकता नहीं है, क्योंकि हमने जाने नहीं दिया है) (लगभग): मैं इस अध्याय में निफ़िग को नहीं समझता, यह बहुत अजीब है, अगर आपके पास विचार हैं, तो लिखें)

7.0 अनुकूलन

टेस्ट कहते हैं कि ज्यादातर मामलों में, SQLite डिस्क पर लिखने के लिए इंतजार करने में सबसे अधिक समय खर्च करता है। तदनुसार, हमें पहले रिकॉर्डिंग को अनुकूलित करना होगा और डिस्क के साथ काम करना होगा। यह अनुभाग कमिट की अखंडता को बनाए रखते हुए, I / O संचालन की संख्या को कम करने की कोशिश में SQLite द्वारा उपयोग की जाने वाली कुछ तकनीकों का वर्णन करता है।

7.1 लेनदेन के बीच कैश की बचत

चरण 3.12 में, आप देख सकते हैं कि जैसे ही संयुक्त लॉक जारी होता है, पूरे उपयोगकर्ता कैश को साफ़ कर दिया जाता है। यह किया जाता है, क्योंकि जब आप एक साझा लॉक के बिना होते हैं, तो अन्य प्रक्रियाएं डेटाबेस फ़ाइल को बदल सकती हैं और आपके उपयोगकर्ता को कैश अप्रचलित कर सकती हैं। इसलिए, प्रत्येक नया लेनदेन डेटाबेस से डेटा पढ़ने से शुरू होगा। यह उतना बुरा नहीं है जितना यह लग सकता है, क्योंकि यह डेटा अभी भी ऑपरेटिंग सिस्टम के डिस्क कैश में सबसे अधिक संभावना है, इसलिए यह केवल ओएस मेमोरी से डेटा की एक प्रति होगी। फिर भी, इसमें समय लगता है।
संस्करण 3.3.14 से शुरू करते हुए, एक तंत्र जोड़ा गया है जो इस संभावना को कम करता है कि डेटा को फिर से पढ़ने की आवश्यकता होगी। लेन-देन के बाद उपयोगकर्ता कैश में डेटा रहता है, और अगले लेनदेन से पहले, SQLite यह देखने के लिए दिखता है कि क्या डेटाबेस फ़ाइल को किसी तरह बदल दिया गया है। यदि ऐसा है, तो उपयोगकर्ता कैश फ्लश हो जाता है। लेकिन अक्सर इस समय फ़ाइल उसी स्थिति में होगी, जिससे हम अनावश्यक पढ़ने के संचालन से बचेंगे।
यह निर्धारित करने के लिए कि एक डेटाबेस फ़ाइल बदल गई है या नहीं, SQLite डेटाबेस हेडर (24 से 27 बाइट्स से) में एक काउंटर का उपयोग करता है, जिसे प्रत्येक फ़ाइल परिवर्तन ऑपरेशन के बाद बढ़ाया जाता है। एक कस्टम SQLite प्रक्रिया लेनदेन पूरा करने से पहले एक काउंटर की स्थिति को बरकरार रखती है। फिर, डेटाबेस पर लॉक प्राप्त करने के बाद, यह काउंटर से तुलना करता है कि यह पहले लेनदेन से पहले क्या था और यदि मान अलग-अलग हैं, तो कैश को फ्लश करता है।

7.2 एक्सक्लूसिव एक्सेस मोड

SQLite 3.3.14 को एक नया फीचर मिला जिसका नाम है "एक्सक्लूसिव एक्सेस मोड"। इस मोड में, SQLite लेनदेन के बाद डेटाबेस फ़ाइल के लिए विशेष लॉक बचाता है। यह डेटाबेस को अन्य प्रक्रियाओं तक पहुंचने से रोकता है, लेकिन SQLite का उपयोग करने के अधिकांश मामलों में, एक समय पर, केवल एक प्रक्रिया डेटाबेस का उपयोग करती है, इसलिए यह कोई समस्या नहीं है। इस प्रकार, डिस्क संचालन की संख्या को कम किया जा सकता है:
  1. पहले लेनदेन के बाद काउंटर को बढ़ाने की आवश्यकता नहीं है। यह अक्सर आपको रोलबैक लॉग और डेटाबेस फ़ाइल के लिए पहला पृष्ठ लिखने का संचालन बचाता है।
  2. अन्य प्रक्रियाएं डेटाबेस को नहीं बदल सकती हैं, इसलिए आपको हर बार उपरोक्त काउंटर की जांच करने की आवश्यकता नहीं है और आपको उपयोगकर्ता कैश को साफ़ करने की आवश्यकता नहीं है।
  3. प्रत्येक लेन-देन पिछले लॉग को अधिलेखित कर सकता है, जिसमें से शीर्षलेख फ़ाइल को हटाने के बजाय शून्य से भरा था। इसके कारण, हमें लॉग फ़ाइल के साथ निर्देशिका को छूने की आवश्यकता नहीं है, साथ ही उस डिस्क सेक्टर को भी तैनात करना चाहिए जिस पर लॉग स्थित था। इस प्रकार, अगला लेन-देन केवल एक नया बनाने और उस पर डेटा लिखने के बजाय पिछले एक के लॉग को अधिलेखित कर देगा, क्योंकि अधिकांश प्रणालियों में पुनर्लेखन बहुत सस्ता है।

तीसरे अनुकूलन का हिस्सा, फ़ाइल को हटाने के बजाय लॉग हेडर को लॉग करना, वास्तव में अनन्य एक्सेस मोड की आवश्यकता होती है, इसे journal_mode_pragma निर्देश का उपयोग करके सक्षम किया जा सकता है, जैसा कि नीचे खंड 7.6 में वर्णित है।

7.3 पेज फ्रीलास्ट लॉग न करें

जब SQLite डेटाबेस से जानकारी हटा दी जाती है, तो हटाए गए जानकारी वाले पृष्ठ फ्रीलास्ट में जोड़े जाते हैं। बाद में प्रविष्टि डेटाबेस फ़ाइल में इन पृष्ठों को अधिलेखित कर देती हैं, आकार में फ़ाइल एक्सटेंशन की आवश्यकता के बिना।
कुछ फ्रीलास्ट पेज में महत्वपूर्ण जानकारी होती है, और अधिक सटीक होने के लिए, अन्य फ्रीलास्ट पेज का स्थान। लेकिन उनमें से अधिकांश में कुछ भी महत्वपूर्ण नहीं है। जो पेज क्रिटिकल नहीं हैं, उन्हें "लीफ" पेज कहा जाता है। हम उनकी सामग्री को बदलने के लिए स्वतंत्र हैं, जबकि डेटाबेस की स्थिति नहीं बदलती है।
चूंकि लीफ पेज की सामग्री इतनी महत्वहीन है, इसलिए SQLite उन्हें कमिट प्रक्रिया के चरण 3.5 में रोलबैक लॉग में संग्रहीत करने से बचता है। यदि शीट पृष्ठ बदला गया है और यह परिवर्तन पुनर्प्राप्ति के दौरान वापस नहीं आता है, तो डेटाबेस को इससे किसी भी तरह से नुकसान नहीं होगा।

7.4 एक-पृष्ठ परिवर्तन और क्षेत्रों के परमाणु रिकॉर्ड

SQLite 3.5.0 के साथ शुरू, नए वर्चुअल फ़ाइल सिस्टम (VFS) इंटरफ़ेस में xDeviceCharacteristics पद्धति है, जो स्टोरेज (डिस्क) के गुणों को लौटाती है। इन गुणों के बीच परमाणु क्षेत्र की रिकॉर्डिंग की संभावना है।
SQLite, डिफ़ॉल्ट रूप से, मान लेता है कि डिस्क रैखिक रूप से लिखती है, एटोमिक रूप से नहीं। लाइन रिकॉर्डिंग सेक्टर के एक छोर से शुरू होती है और बाइट द्वारा बाइट अपने दूसरे छोर तक पहुंच जाती है। यदि रिकॉर्डिंग के दौरान बिजली की विफलता होती है, तो सेक्टर का हिस्सा क्षतिग्रस्त हो सकता है (पुराने डेटा शामिल हैं)। क्षेत्रों की परमाणु रिकॉर्डिंग में, या तो पूरे क्षेत्र को अधिलेखित कर दिया जाएगा, या संपूर्ण क्षेत्र एक ही स्थिति में रहेगा।
अधिकांश आधुनिक ड्राइव परमाणु क्षेत्र के लेखन का समर्थन करते हैं। जब बिजली की हानि होती है, तो डिस्क सभी अनुसूचित रिकॉर्डिंग कार्यों को पूरा करने के लिए अपने कैपेसिटर और / या पैनकेक रोटेशन ऊर्जा में संग्रहीत ऊर्जा का उपयोग करता है। फिर भी, सिस्टम राइट कॉल और डिस्क के इलेक्ट्रॉनिक्स के बीच इतनी सारी परतें हैं कि हमने सभी प्लेटफार्मों पर एक निराशावादी धारणा बनाने का फैसला किया कि सेक्टर रैखिक रूप से लिखे गए हैं।
जब सेक्टर रिकॉर्ड परमाणु होता है, और डेटाबेस पेज का आकार सेक्टर आकार के बराबर होता है, अगर यह सिर्फ एक पृष्ठ को बदलने के लिए आवश्यक है, तो SQLite लॉगिंग प्रक्रिया को पूरी तरह से छोड़ देगा, इसके बजाय, सीधे डेटाबेस फ़ाइल में सीधे परिवर्तन लिखें। और परिवर्तन काउंटर को अलग से बढ़ाया जाएगा, क्योंकि ऊर्जा को बंद करने से यहां कोई नुकसान नहीं होगा, भले ही यह काउंटर में परिवर्तन से पहले हो।

7.5 फाइल सिस्टम सेफ अपेंड फीचर के साथ

3.5.0 संस्करण में पेश किया गया एक अन्य अनुकूलन सुरक्षित एपेंड डिस्क सुविधा का उपयोग करता है। जैसा कि आपको याद है, आमतौर पर SQLite मानता है कि जब किसी डेटा का नया टुकड़ा किसी फ़ाइल में जोड़ा जाता है, तो उसका आकार पहले बढ़ जाता है, और उसके बाद ही डेटा लिखा जाता है। इसलिए यदि डिस्क इन घटनाओं के बीच ऊर्जा खो देता है, तो फ़ाइल में अंत में मृत डेटा होगा। xDeviceCharacteristics में से एक विधि हमें बताती है कि क्या डिस्क एक सुरक्षित एपेंड कर सकती है। इस सुविधा को इस तरह से लागू किया जाता है कि डिस्क, इसके विपरीत, पहले "प्रचारित" क्षेत्र में डेटा लिखता है, जिसके बाद यह फ़ाइल का आकार बढ़ाता है और उस क्षेत्र को इस फ़ाइल को देता है। इस प्रकार, रिकॉर्डिंग के दौरान भी ऊर्जा का नुकसान भयानक नहीं है (वास्तव में, यह एक परमाणु परिशिष्ट है)।
सुरक्षित एपेंड सक्षम होने के साथ, SQLite -1 के बराबर रोलबैक लॉग के हेडर में पृष्ठों की संख्या छोड़ देता है। जब लॉग में -1 होता है, तो प्रक्रिया समझती है कि लॉग के आकार से पृष्ठों की संख्या की गणना की जानी चाहिए। इसके लिए धन्यवाद, हम एक फ्लश ऑपरेशन को बचाते हैं।

7.6 लॉग हटाने से इंकार करना

कई प्रणालियों पर, फ़ाइल हटाना एक महंगा ऑपरेशन है। तो SQLite में आप लॉग डिलीट को डिसेबल कर सकते हैं। इसके बजाय, आप फ़ाइल को शून्य लंबाई तक ट्रिम कर सकते हैं, या शीर्ष लेख को शून्य से भर सकते हैं। फ़ाइल को ट्रिम करना अधिक लाभदायक है, क्योंकि तब आपको उस निर्देशिका को छूने की आवश्यकता नहीं है जिसमें यह निहित है, क्योंकि इस मामले में फ़ाइल स्वयं ही रहेगी। दूसरी ओर, हेडर को ओवरराइट करते हुए, आप फ़ाइल की लंबाई (इस फाइल का इनकोड) को नहीं छू सकते हैं और डिस्क पर नए मुक्त किए गए क्षेत्रों को डील करने में समय बर्बाद नहीं करने देते हैं। फिर, अगले लेन-देन पर, एक मौजूदा फ़ाइल में लॉग बनाया जाएगा, इसे अधिलेखित करना, यह भी जोड़ से तेज होगा।
यदि आप PERSIST में journal_mode विकल्प सेट करते हैं, तो SQLite इस रणनीति का पालन करेगा। ( PRAGMA journal_mode=PERSIST )
इस मोड का उपयोग आमतौर पर अधिकांश प्रणालियों पर ध्यान देने योग्य प्रदर्शन को बढ़ावा देता है। बेशक वहाँ एक माइनस है - लॉग डिस्क पर बने रहते हैं और जगह खाते हैं।इस तरह के लॉग को हटाने का एकमात्र सुरक्षित तरीका लॉगिंग मोड के साथ लेनदेन करना है DELETE:
 PRAGMA journal_mode=DELETE BEGIN EXCLUSIVE COMMIT; 

यदि आप मैन्युअल रूप से फ़ाइलों को हटाने की कोशिश करते हैं, तो आप ऐसी स्थिति में पहुंच सकते हैं जहां लॉग अभी भी प्रगति में लेनदेन से संबंधित हैं।
संस्करण 3.6.4 के साथ शुरू, मोड भी समर्थित है TRUNCATE:
 PRAGMA journal_mode=TRUNCATE 

. , , , . , , . , TRUNCATE (fsync, flush). . TRUNCATE — , , . , TRUNCATE, , .
एक तुल्यकालिक फ़ाइल सिस्टम के साथ एम्बेडेड सिस्टम पर, TRUNCATE आमतौर पर PERSIST की तुलना में धीमा है। पहली प्रतिबद्ध गति में समान है, लेकिन बाद में लेनदेन धीमा है, क्योंकि डेटा को अधिलेखित करना फ़ाइल के अंत में संलग्न होने की तुलना में तेज़ है। TRUNCATE के बाद नए लॉग हमेशा जोड़े जाएंगे, जबकि एक निरंतर रणनीति के साथ वे पुराने को अधिलेखित कर देंगे।

8.0 परमाणु प्रतिबद्ध परीक्षण

SQLite डेवलपर्स को भरोसा है कि यह प्रणाली बिजली की विफलता और विभिन्न सिस्टम विफलताओं के सामने विश्वसनीय है। स्वचालित परीक्षण प्रक्रिया नकली विफलताओं से उबरने की अपनी क्षमता के लिए SQLite का परीक्षण करती है। हम इसे क्रैश टेस्ट कहते हैं।
SQLite VFS, , - . , «» - . , — , , . . , .

9.0

SQLite में परमाणु प्रतिबद्ध तंत्र बहुत विश्वसनीय है, लेकिन अगर अंतर्निहित परतें गलत काम करती हैं तो इसे तोड़ा जा सकता है। यह खंड कई संभावित परिदृश्यों का वर्णन करता है जिसमें सिस्टम की विफलता या बिजली की विफलता के कारण डेटाबेस क्षतिग्रस्त हो सकता है।

9.1 महत्वपूर्ण ताला कार्यान्वयन

SQLite फ़ाइल लॉक का उपयोग यह सुनिश्चित करने के लिए करता है कि केवल एक प्रक्रिया में एक समय में डेटाबेस को संशोधित करने की क्षमता हो। लॉकिंग तंत्र VFS स्तर पर लागू किया जाता है और विभिन्न ऑपरेटिंग सिस्टमों के बीच भिन्न होता है। SQLite इन कार्यान्वयनों पर निर्भर करता है, और अगर उनके स्तर पर कुछ गलत होता है और दो या अधिक प्रक्रियाएं डेटाबेस फ़ाइल में लिख सकती हैं, तो इसके परिणामस्वरूप डेटाबेस में भ्रष्टाचार हो सकता है।
हमें विंडोज नेटवर्क फ़ाइल सिस्टम और एनएफएस पर बग रिपोर्ट मिली, जिसमें ताले अपेक्षा के अनुरूप काम नहीं कर रहे थे। हम इन रिपोर्टों की पुष्टि नहीं कर सकते हैं, लेकिन चूंकि लॉक नेटवर्क फ़ाइल सिस्टम पर लागू करने के लिए काफी कठिन हैं, इसलिए हमारे पास यह संदेह करने का कोई कारण नहीं है कि ये बग वास्तव में मौजूद हैं। हम आपको सलाह देते हैं कि नेटवर्क फाइल सिस्टम के शीर्ष पर SQLite का उपयोग न करें, यदि केवल बड़े प्रदर्शन के नुकसान के कारण।
SQLite, Max OS X , , Apple. , , . , () , AFP , dot-file (, ), , .

9.2

SQLite fsync Unix- FlushFileBuffers win32, . , , , . FlushFileBuffers Windows. Linux fsync , . , , , , , , , .
Mac PRAGMA fillfsync=ON;, जो डिस्क पर पेनकेक्स के लिए डेटा के पूर्ण रीसेट की गारंटी देगा, और न केवल डिस्क कैश में। लेकिन फ़ुलफ़िस्क्यू क्रियान्वयन धीमा है और डिस्क से संबंधित अन्य कार्यों को धीमा कर देगा।

9.3 अपूर्ण फ़ाइल विलोपन

SQLite मानता है कि फ़ाइल को हटाना उपयोगकर्ता प्रक्रिया के दृष्टिकोण से एक परमाणु संचालन है। यदि फ़ाइल हटाने के दौरान ऊर्जा की हानि होती है, तो SQLite फ़ाइल को पूरी तरह से सहेजने या हटाने की अपेक्षा करता है। लेन-देन को उन प्रणालियों पर परमाणु नहीं माना जा सकता है जो अलग तरीके से काम करते हैं।

9.4 डेटाबेस फ़ाइल को बाहर से संशोधित करना

SQLite डेटाबेस डिस्क पर नियमित फ़ाइलों में निहित है जिसे अन्य प्रक्रियाओं द्वारा खोला जा सकता है और संशोधित किया जा सकता है। कोई भी प्रक्रिया एक डेटाबेस फ़ाइल खोल सकती है और इसे "खराब" डेटा के साथ भर सकती है। ऐसे हस्तक्षेप से खुद को बचाने के लिए SQLite कुछ भी नहीं कर सकता है।

9.5

, , , . SQLite , . , .
, , , .
यदि डेटाबेस फ़ाइल पर प्रतीकात्मक (या कठोर) लिंक बनाए जाते हैं, तो उस लिंक के नाम के आधार पर लॉग का नाम दिया जाएगा, जिसके माध्यम से डेटाबेस खोला गया था। यदि कोई क्रैश होता है और डेटाबेस को किसी अन्य लिंक (या मूल फ़ाइल के माध्यम से) के माध्यम से खोला जाता है, तो हॉट लॉग को नहीं उठाया जाएगा और आप क्षतिग्रस्त डेटाबेस के साथ काम करेंगे।
कभी-कभी एक बिजली की विफलता एक ऐसी स्थिति का कारण बन सकती है जहां नई संशोधित फाइलें गायब हो जाती हैं और अंत में समाप्त हो जाती हैं/lost+found . , , . SQLite (fsync) . , - , , . , SQLite, , . , ( , ), SQLite .

Source: https://habr.com/ru/post/In181584/


All Articles