SQLite समवर्ती पहुँच


177

SQLite3 क्या सुरक्षित रूप से एक ही DB से पढ़ने / लिखने की कई प्रक्रियाओं द्वारा समवर्ती पहुँच को संभालता है? क्या उस पर कोई अपवाद हैं?


3
मैं बाउंटी गोल का उल्लेख करना भूल गया : अधिकांश उत्तर यह कहते हैं कि यह ठीक है: "SQLite काफी तेज है", "SQLite संक्षिप्तता को अच्छी तरह से संभालता है" आदि, लेकिन, imho, विस्तार से जवाब न दें / स्पष्ट रूप से स्पष्ट न करें कि क्या होता है यदि दो लेखन संचालन होते हैं ठीक उसी समय (सैद्धांतिक बहुत दुर्लभ मामला) पर पहुंचेगा। 1) क्या यह एक त्रुटि को ट्रिगर करेगा और कार्यक्रम को बाधित करेगा? या 2) क्या दूसरा लेखन ऑपरेशन तब तक रुकेगा जब तक कि पहला खत्म नहीं हो जाता? या 3) क्या लिखने के ऑपरेशन में से एक को खारिज कर दिया जाएगा (डेटा हानि?) 4) कुछ और? समवर्ती लेखन की सीमाओं को जानना कई स्थितियों में उपयोगी हो सकता है।
बसज

7
@Basj संक्षेप में, 2) यह प्रतीक्षा करेगा और कई बार (कॉन्फ़िगर करने योग्य) पुन: प्रयास करेगा, 1) एक त्रुटि ट्रिगर करें, SQLITE_BUSY.3) आप एक कॉलबैक को हैंडल SQLITE_BUSY त्रुटियों को पंजीकृत कर सकते हैं।
obgnaw

जवाबों:


112

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

अधिकांश डेस्कटॉप / लैपटॉप / टैबलेट / फोन अनुप्रयोगों के लिए, SQLite पर्याप्त रूप से तेज़ है क्योंकि पर्याप्त संगामिति नहीं है। (फ़ायरफ़ॉक्स बुकमार्क, इतिहास, आदि के लिए बड़े पैमाने पर SQLite का उपयोग करता है)

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

यदि आप वास्तव में तेजी से पढ़ना / लिखना चाहते हैं, तो इन-मेमोरी SQLite डेटाबेस का उपयोग करें । रैम डिस्क की तुलना में तीव्रता के कई आदेश हैं।


16
ओपी दक्षता और गति के बारे में नहीं पूछता है, लेकिन समवर्ती पहुंच के बारे में पूछता है। वेब सर्वर का इससे कोई लेना-देना नहीं है। मेमोरी डेटाबेस में समान है।
जेरेकाइक

1
आप एक हद तक सही हैं लेकिन दक्षता / गति एक भूमिका निभाती है। तेज़ पहुँच का मतलब है कि ताले के इंतज़ार में बिताया गया समय कम है, जिससे SQLite के समसामयिक प्रदर्शन की कमियों को कम किया जा सकता है। विशेष रूप से, यदि आपके पास कुछ और तेज़ लिखता है, तो DB को उपयोगकर्ता के लिए कोई समसामयिक मुद्दे नहीं दिखेंगे।
काबोस

1
आप इन-मेमोरी साइक्लाइट डेटाबेस में समवर्ती पहुँच कैसे प्रबंधित करेंगे?
P-Gn

42

हां, SQLite कंसर्ट को अच्छी तरह से हैंडल करता है, लेकिन यह एक प्रदर्शन कोण से सबसे अच्छा नहीं है। मैं जो बता सकता हूं, उससे कोई अपवाद नहीं है। विवरण SQLite की साइट पर हैं: https://www.sqlite.org/lockingv3.html

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


2
यहां विभिन्न प्लेटफार्मों पर मुद्दों के बारे में कुछ टिप्पणियां दी गई हैं , अर्थात् एनएफएस फाइल सिस्टम, और विंडोज (हालांकि यह केवल विंडोज के पुराने संस्करणों से संबंधित हो सकता है ...)
नैट

1
क्या PHP में SQLite3 डेटाबेस को लोड करना संभव है जो PHP के सभी उपयोगकर्ताओं के लिए उपयोग किया जाता है? मैं अनुमान लगा रहा हूं कि यह प्रक्रियागत नहीं है
Anon343224user

1
@foxyfennec .. एक शुरुआती बिंदु, हालांकि SQLite इस उपयोग के मामले के लिए इष्टतम डीबी नहीं हो सकता है। sqlite.org/inmemorydb.html
kingPuppy

37

हाँ यह करता है। आइए जानें इसका कारण

SQLite ट्रांसेक्शनल है

SQLite में एकल लेनदेन में सभी परिवर्तन या तो पूरी तरह से होते हैं या बिल्कुल नहीं होते हैं

इस तरह के ACID समर्थन के साथ-साथ समवर्ती रीड / राइट्स 2 तरीकों से प्रदान किए जाते हैं - तथाकथित जर्नलिंग का उपयोग करते हुए (इसे " पुराना तरीका " कहते हैं) या राइट-फॉरवर्ड लॉगिंग (इसे " नया तरीका " कहते हैं)

जर्नलिंग (पुराना तरीका)

इस मोड में SQLite DATABASE-LEVEL लॉकिंग का उपयोग करता है । यह समझने के लिए महत्वपूर्ण बिंदु है।

इसका मतलब है कि जब भी कुछ पढ़ने / लिखने की जरूरत होती है तो वह पहले ENTIRE डेटाबेस फाइल पर एक लॉक प्राप्त करता है । एकाधिक पाठक समानांतर में किसी चीज़ को सह सकते हैं और पढ़ सकते हैं

यह लिखने के दौरान यह सुनिश्चित करता है कि एक विशेष ताला प्राप्त किया गया है और कोई अन्य प्रक्रिया एक साथ नहीं पढ़ / लिख रही है और इसलिए लिखना सुरक्षित है।

यही कारण है कि यहाँ वे कह रहे हैं SQlite धारावाहिक लेनदेन को लागू करता है

मुसीबतों

जैसा कि हर बार एक पूरे डेटाबेस को लॉक करने की आवश्यकता होती है और हर कोई एक प्रक्रिया के लिए इंतजार कर रहा है जो कि लेखन संगामिति को संभालती है और इस तरह के समवर्ती लेखन / रीड काफी कम प्रदर्शन के होते हैं

रोलबैक / की कटौती

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

लिखें-आगे लॉगिंग या वाल (नया तरीका)

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

परिणामस्वरूप, लेखक लेखकों के साथ प्रतिस्पर्धा नहीं करते हैं और प्रदर्शन पुराने तरीके की तुलना में बहुत बेहतर है।

चेतावनियां

SQlite काफी हद तक अंतर्निहित फाइल सिस्टम लॉकिंग कार्यक्षमता पर निर्भर करता है, इसलिए इसका उपयोग सावधानी के साथ किया जाना चाहिए, यहां अधिक विवरण

आपको डेटाबेस में चलाने की भी संभावना है, लॉक की गई त्रुटि, विशेष रूप से जर्नल की गई मोड में, ताकि आपके ऐप को इस त्रुटि को ध्यान में रखते हुए डिज़ाइन किया जाए


34

लगता है किसी ने भी वाल (लिख अहेड लॉग) मोड का उल्लेख नहीं किया है। सुनिश्चित करें कि लेनदेन ठीक से व्यवस्थित हैं और वाल मोड सेट के साथ, डेटाबेस को बंद रखने की कोई आवश्यकता नहीं है, जबकि लोग अपडेट पढ़ रहे हैं, जबकि लोग चीजों को पढ़ रहे हैं।

एकमात्र मुद्दा यह है कि कुछ बिंदु पर वाल को मुख्य डेटाबेस में फिर से शामिल करने की आवश्यकता होती है, और ऐसा तब होता है जब डेटाबेस का अंतिम कनेक्शन बंद हो जाता है। एक बहुत व्यस्त साइट के साथ आपको लग सकता है कि सभी कनेक्शनों को बंद होने में कुछ सेकंड लगेंगे, लेकिन प्रति दिन 100K हिट कोई समस्या नहीं होनी चाहिए।


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

यह उल्लेख के लायक है कि किसी लेखक की प्रतीक्षा करने का डिफ़ॉल्ट समय 5 सेकंड है और उसके बाद database is lockedत्रुटि लेखक द्वारा उठाई जाएगी
mirhossein

16

2019 में, दो नए समवर्ती लेखन विकल्प जारी नहीं किए गए हैं लेकिन अलग-अलग शाखाओं में उपलब्ध हैं।

"PRAGMA journal_mode = wal2"

नियमित रूप से "वाल" मोड पर इस जर्नल मोड का लाभ यह है कि लेखक एक वॉल फाइल में लिखना जारी रख सकता है जबकि दूसरा चेकपॉइंट करता है।

BEGIN CONCURRENT - विस्तृत डॉक्टर का लिंक

BEGIN CONCURRENT एन्हांसमेंट कई लेखकों को एक साथ लेनदेन लिखने की प्रक्रिया करने की अनुमति देता है यदि डेटाबेस "वाल" या "wal2" मोड में है, हालांकि सिस्टम अभी भी COMMIT कमांड्स को क्रमबद्ध करता है।

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

साथ में वे शुरू-समवर्ती-वाल 2 या प्रत्येक में एक अलग शाखा में मौजूद हैं


1
क्या हमारे पास कोई विचार है जब वे सुविधाएँ रिलीज़ संस्करण में अपना रास्ता बनाएंगी? वे वास्तव में मेरे लिए काम आ सकते हैं।
पीटर मूर

2
कोई जानकारी नहीं। आप शाखाओं से आसानी से बना सकते हैं। .NET के लिए मेरे पास निम्न-स्तरीय इंटरफ़ेस के साथ एक पुस्तकालय है और WAL2 + समवर्ती + FTS5 शुरू करें: github.com/Spreads/Spreads.SQLite
VB

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

2
इस धागे को देखें सामान्य रूप से github.com/Expensify/Bedrock/issues/65 और Bedrock। वे इसे उत्पादन में उपयोग करते हैं और उस begin concurrentसामान को धक्का देते हैं ।
वीबी

13

SQLite में डेटाबेस स्तर पर एक पाठक-लेखक लॉक होता है। एकाधिक कनेक्शन (संभवतः विभिन्न प्रक्रियाओं के स्वामित्व वाले) एक ही समय में एक ही डेटाबेस से डेटा पढ़ सकते हैं, लेकिन केवल एक ही डेटाबेस को लिख सकता है।

SQLite एक साथ पाठकों की एक असीमित संख्या का समर्थन करता है, लेकिन यह केवल एक लेखक को किसी भी समय पर अनुमति देगा। कई स्थितियों के लिए, यह कोई समस्या नहीं है। लेखक कतार से। प्रत्येक एप्लिकेशन अपना डेटाबेस तेज़ी से काम करता है और आगे बढ़ता है, और कोई भी लॉक कुछ दर्जन से अधिक मिलीसेकंड तक नहीं रहता है। लेकिन कुछ एप्लिकेशन ऐसे होते हैं जिनके लिए अधिक संगति की आवश्यकता होती है, और उन अनुप्रयोगों को एक अलग समाधान की आवश्यकता हो सकती है। - SQLite @ SQLite.org के लिए उपयुक्त उपयोग

पाठकों-लेखक लॉक स्वतंत्र लेनदेन प्रसंस्करण को सक्षम करता है और इसे डेटाबेस स्तर पर अनन्य और साझा किए गए ताले का उपयोग करके कार्यान्वित किया जाता है।

एक डेटाबेस पर एक लेखन ऑपरेशन करने से पहले एक विशेष लॉक प्राप्त किया जाना चाहिए। अनन्य लॉक प्राप्त होने के बाद, अन्य कनेक्शनों से पढ़ने और लिखने दोनों का संचालन अवरुद्ध हो जाता है जब तक कि ताला फिर से जारी नहीं हो जाता।

समवर्ती लेखन के मामले के लिए कार्यान्वयन विवरण

SQLite में एक लॉक टेबल है जो डेटाबेस को लॉक करने में मदद करता है जितना संभव हो लेखन ऑपरेशन के दौरान अधिकतम समरूपता सुनिश्चित करने के लिए।

प्रारंभिक स्थिति UNLOCKED है, और इस स्थिति में, कनेक्शन अभी तक डेटाबेस तक नहीं पहुँचा है। जब एक प्रक्रिया एक डेटाबेस से जुड़ी होती है और यहां तक ​​कि BEGIN के साथ एक लेनदेन शुरू किया गया है, तो कनेक्शन अभी भी UNLOCKED स्थिति में है।

UNLOCKED राज्य के बाद, अगला राज्य SHARED स्थिति है। डेटाबेस से डेटा को पढ़ने (लिखने नहीं) करने में सक्षम होने के लिए, कनेक्शन को पहले SHARED लॉक दर्ज करके, SHARED स्थिति दर्ज करनी होगी। एक ही समय में कई कनेक्शन साझा ताले प्राप्त और बनाए रख सकते हैं, इसलिए कई कनेक्शन एक ही डेटाबेस से एक ही समय में डेटा पढ़ सकते हैं। लेकिन जब तक यहां तक ​​कि केवल एक साझा ताला अप्रबंधित रहता है, तब तक कोई भी कनेक्शन डेटाबेस को लिखने को सफलतापूर्वक पूरा नहीं कर सकता है।

यदि कोई कनेक्शन डेटाबेस में लिखना चाहता है, तो उसे पहले एक RESERVED लॉक प्राप्त करना होगा।

एक समय में केवल एक एकल आरक्षित ताला सक्रिय हो सकता है, हालांकि कई साझा ताले एक एकल RESERVED लॉक के साथ सह-अस्तित्व में हो सकते हैं। RESERVED, PENING से भिन्न होता है, जबकि RESERVED लॉक होने पर नए SHARED ताले प्राप्त किए जा सकते हैं। - फाइल लॉकिंग और कंसीलर SQLite वर्जन 3 @ SQLite.org में

एक बार जब कोई कनेक्शन एक RESERVED लॉक प्राप्त करता है, तो यह डेटाबेस संशोधन संचालन शुरू कर सकता है, हालांकि ये संशोधन केवल बफर में किया जा सकता है, बजाय वास्तव में डिस्क पर लिखे। रीडआउट सामग्री में किए गए संशोधन मेमोरी बफर में सहेजे जाते हैं। जब कोई कनेक्शन एक संशोधन (या लेनदेन) प्रस्तुत करना चाहता है, तो RESERVED लॉक को EXCLUSIVE लॉक में अपग्रेड करना आवश्यक है। लॉक प्राप्त करने के लिए, आपको पहले लॉक को PENDING लॉक को उठाना होगा।

PENDING लॉक का मतलब है कि लॉक को होल्ड करने की प्रक्रिया जल्द से जल्द डेटाबेस को लिखना चाहता है और अभी सभी मौजूदा SHARED लॉक को क्लियर करने का इंतज़ार कर रहा है ताकि इसे EXCLUSIVE लॉक मिल सके। यदि कोई PENDING लॉक सक्रिय है, तो डेटाबेस के विरुद्ध कोई नया साझा किए गए ताले की अनुमति नहीं है, हालांकि मौजूदा SHARED ताले को जारी रखने की अनुमति है।

डेटाबेस फ़ाइल को लिखने के लिए एक EXCLUSIVE लॉक की आवश्यकता होती है। फ़ाइल पर केवल एक EXCLUSIVE लॉक की अनुमति है और किसी अन्य प्रकार के किसी अन्य लॉक को EXCLUSIVE लॉक के साथ सह-अस्तित्व की अनुमति नहीं है। समवर्ती अधिकतम करने के लिए, SQLite उस समय की मात्रा को कम करने के लिए काम करता है, जिसमें EXCLUSIVE ताले लगे हुए हैं। - फाइल लॉकिंग और कंसीलर SQLite वर्जन 3 @ SQLite.org में

तो आप कह सकते हैं कि SQLite सुरक्षित रूप से एक ही DB के लिए कई प्रक्रियाओं द्वारा समवर्ती पहुँच को संभालता है क्योंकि यह इसका समर्थन नहीं करता है! आप मिल जाएगा SQLITE_BUSYया SQLITE_LOCKEDदूसरे लेखक के लिए जब यह फिर से प्रयास करें सीमा पूरी करता है।


धन्यवाद। 2 लेखकों के साथ कोड का एक उदाहरण यह समझने के लिए सुपर शानदार होगा कि यह कैसे काम करता है।
बसज

1
@ संक्षेप में, sqlite में डेटाबेस फ़ाइल पर Read-Write Lock होता है। यह समवर्ती फ़ाइल लिखने के समान है। और वाल के साथ, अभी भी समवर्ती लेखन नहीं कर सकता है, लेकिन वाल लेखन को गति दे सकता है, और पढ़ना और लिखना समवर्ती हो सकता है। और वाल नए नए लॉक की तरह पेश करते हैं जैसे कि Wal_READ_LOCK, WAL_WRITE_LOCK।
obgnaw

2
क्या आप एक कतार का उपयोग कर सकते हैं और कई धागे कतार में फ़ीड कर सकते हैं और कतार में SQL कथन का उपयोग करते हुए DB को सिर्फ एक धागा लिख ​​सकते हैं। कुछ इस
गेब्रियल

7

यह धागा पुराना है, लेकिन मुझे लगता है कि यह मेरे परीक्षण के परिणाम को sqlite पर साझा करने के लिए अच्छा होगा: मैंने पायथन प्रोग्राम के 2 उदाहरणों (अलग-अलग प्रक्रियाओं को एक ही कार्यक्रम) चलाया और स्टेटमेंट का चयन करें और EXDUSIVE लॉक और टाइमआउट सेट के साथ लेन-देन के भीतर sql कमांड को सेट करें। एक ताला पाने के लिए 10 सेकंड, और परिणाम निराशाजनक थे। 10000 चरण पाश में किया गया हर उदाहरण:

  • अनन्य लॉक के साथ db से कनेक्ट करें
  • काउंटर पढ़ने के लिए एक पंक्ति पर चयन करें
  • 1 द्वारा संवर्धित काउंटर के बराबर नए मूल्य के साथ पंक्ति को अपडेट करें
  • db से घनिष्ठ संबंध

यहां तक ​​कि अगर sqlite को लेनदेन पर अनन्य लॉक दिया गया है, तो वास्तव में निष्पादित चक्रों की कुल संख्या 20 000 के बराबर नहीं थी, लेकिन कम (दोनों प्रक्रियाओं के लिए गिने गए एकल काउंटर पर पुनरावृत्तियों की कुल संख्या)। पायथन प्रोग्राम ने लगभग एक भी अपवाद नहीं चुना (केवल एक बार 20 निष्पादन के लिए चयन के दौरान)। परीक्षण के क्षण में साइक्लाइट का संशोधन 3.6.20 और अजगर v3.3 सेंटोस 6.5 था। मेरी राय में इस तरह की नौकरी के लिए अधिक विश्वसनीय उत्पाद ढूंढना बेहतर है या एकल अद्वितीय प्रक्रिया / धागे के लिए साइक्लाइट को प्रतिबंधित करता है।


5
ऐसा लगता है कि आपको अजगर पर ताला लगाने के लिए कुछ जादुई शब्द कहने की आवश्यकता है, जैसा कि यहां चर्चा की गई है: stackoverflow.com/a/12848059/1048959 इस तथ्य के बावजूद कि अजगर साइक्लाइट प्रलेखन आपको लगता है कि with conपर्याप्त है।
डैन स्टाल्के
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.