Database
 sql >> डेटाबेस >  >> RDS >> Database

स्नैपशॉट अलगाव स्तर

[ पूरी श्रृंखला के लिए सूचकांक देखें ]

समवर्ती समस्याएं उसी तरह कठिन होती हैं जैसे बहु-थ्रेडेड प्रोग्रामिंग कठिन होती है। जब तक क्रमबद्ध अलगाव का उपयोग नहीं किया जाता है, तब तक टी-एसक्यूएल लेनदेन को कोड करना कठिन हो सकता है जो हमेशा सही ढंग से कार्य करेगा जब अन्य उपयोगकर्ता एक ही समय में डेटाबेस में परिवर्तन कर रहे हों।

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

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

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

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

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

एसिड गुण और स्नैपशॉट अलगाव

स्नैपशॉट अलगाव SQL मानक में परिभाषित अलगाव स्तरों में से एक नहीं है, लेकिन फिर भी इसकी तुलना अक्सर वहां परिभाषित 'समवर्ती घटना' का उपयोग करके की जाती है। उदाहरण के लिए, निम्न तुलना तालिका को किम्बर्ली एल. ट्रिप और नील ग्रेव्स द्वारा SQL सर्वर तकनीकी आलेख, "SQL सर्वर 2005 पंक्ति संस्करण-आधारित लेन-देन अलगाव" से पुन:प्रस्तुत किया गया है:

पॉइंट-इन-टाइम व्यू providing प्रदान करके प्रतिबद्ध डेटा . का , स्नैपशॉट अलगाव वहां दिखाए गए सभी तीन समवर्ती घटनाओं से सुरक्षा प्रदान करता है। डर्टी रीडिंग को रोका जाता है क्योंकि केवल प्रतिबद्ध डेटा दिखाई देता है, और स्नैपशॉट की स्थिर प्रकृति गैर-दोहराए जाने योग्य रीड और फैंटम दोनों का सामना करने से रोकती है।

हालाँकि, यह तुलना (और विशेष रूप से हाइलाइट किया गया अनुभाग) केवल यह दर्शाता है कि स्नैपशॉट और क्रमिक अलगाव स्तर समान तीन विशिष्ट घटनाओं को रोकते हैं। इसका मतलब यह नहीं है कि वे सभी मामलों में समान हैं। महत्वपूर्ण रूप से, SQL-92 मानक केवल तीन घटनाओं के संदर्भ में क्रमिक अलगाव को परिभाषित नहीं करता है। मानक की धारा 4.28 पूरी परिभाषा देती है:

<ब्लॉकक्वॉट>

अलगाव स्तर SERIALIZABLE पर समवर्ती SQL-लेन-देन का निष्पादन क्रमबद्ध होने की गारंटी है। एक क्रमिक निष्पादन को समवर्ती रूप से निष्पादित SQL-लेन-देन के संचालन के निष्पादन के रूप में परिभाषित किया गया है जो समान SQL-लेन-देन के कुछ सीरियल निष्पादन के समान प्रभाव उत्पन्न करता है। एक सीरियल निष्पादन वह है जिसमें प्रत्येक SQL-लेन-देन अगले SQL-लेन-देन शुरू होने से पहले पूरा होने के लिए निष्पादित होता है।

यहां निहित गारंटियों की सीमा और महत्व अक्सर चूक जाते हैं। इसे सरल भाषा में बताने के लिए:

<ब्लॉकक्वॉट>

कोई भी क्रमिक लेन-देन जो अकेले चलने पर सही ढंग से निष्पादित होता है, समवर्ती लेनदेन के किसी भी संयोजन के साथ सही ढंग से निष्पादित होता रहेगा, या इसे एक त्रुटि संदेश (आमतौर पर SQL सर्वर के कार्यान्वयन में एक गतिरोध) के साथ वापस लाया जाएगा।

स्नैपशॉट अलगाव सहित गैर-क्रमबद्ध अलगाव स्तर, शुद्धता की समान मजबूत गारंटी प्रदान नहीं करते हैं।

पुराना डेटा

स्नैपशॉट अलगाव लगभग आकर्षक रूप से सरल लगता है। पठन हमेशा एक ही समय में प्रतिबद्ध डेटा से आते हैं, और लिखने के विरोध स्वचालित रूप से पहचाने और संभाले जाते हैं। यह समवर्ती-संबंधी सभी कठिनाइयों के लिए एक सही समाधान कैसे नहीं है?

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

स्क्यू लिखें

स्नैपशॉट अलगाव कुछ हद तक संबंधित घटना के लिए भी कमजोर है जिसे स्क्यू लिखना कहा जाता है। पुराने डेटा को पढ़ना इसमें एक भूमिका निभाता है, लेकिन यह समस्या यह स्पष्ट करने में भी मदद करती है कि 'विरोध का पता लगाना' स्नैपशॉट क्या करता है और क्या नहीं करता है।

लेखन तिरछा तब होता है जब दो समवर्ती लेनदेन प्रत्येक डेटा को पढ़ते हैं जिसे अन्य लेनदेन संशोधित करता है। कोई लेखन विरोध नहीं होता है क्योंकि दो लेन-देन अलग-अलग पंक्तियों को संशोधित करते हैं। न तो लेन-देन दूसरे द्वारा किए गए परिवर्तनों को देखता है, क्योंकि दोनों एक बिंदु से उन परिवर्तनों को किए जाने से पहले पढ़ रहे हैं।

सफेद और काले संगमरमर की समस्या लिखने का एक उत्कृष्ट उदाहरण है, लेकिन मैं यहां एक और सरल उदाहरण दिखाना चाहता हूं:

-- Create two empty tables
CREATE TABLE A (x integer NOT NULL);
CREATE TABLE B (x integer NOT NULL);
 
-- Connection 1
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION;
INSERT A (x) SELECT COUNT_BIG(*) FROM B;
 
-- Connection 2
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION;
INSERT B (x) SELECT COUNT_BIG(*) FROM A;
COMMIT TRANSACTION;
 
-- Connection 1
COMMIT TRANSACTION;

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

एक संघर्ष का पता लगाने की सूक्ष्मता

एक स्नैपशॉट लिखने का विरोध तब होता है जब एक स्नैपशॉट लेनदेन एक पंक्ति को संशोधित करने का प्रयास करता है जिसे स्नैपशॉट लेनदेन शुरू होने के बाद किए गए किसी अन्य लेनदेन द्वारा संशोधित किया गया है। यहां दो बारीकियां हैं:

  1. लेन-देन को वास्तव में बदलने की आवश्यकता नहीं होती है कोई डेटा मान; और
  2. लेन-देन के लिए किसी सामान्य कॉलम को संशोधित करने की आवश्यकता नहीं है .

निम्नलिखित स्क्रिप्ट दोनों बिंदुओं को प्रदर्शित करती है:

-- Test table
CREATE TABLE dbo.Conflict
(
    ID1 integer UNIQUE,
    Value1 integer NOT NULL,
    ID2 integer UNIQUE,
    Value2 integer NOT NULL
);
 
-- Insert one row
INSERT dbo.Conflict
    (ID1, ID2, Value1, Value2)
VALUES
    (1, 1, 1, 1);
 
-- Connection 1
BEGIN TRANSACTION;
 
UPDATE dbo.Conflict
SET Value1 = 1
WHERE ID1 = 1;
 
-- Connection 2
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION;
 
UPDATE dbo.Conflict
SET Value2 = 1
WHERE ID2 = 1;
 
-- Connection 1
COMMIT TRANSACTION;

निम्नलिखित पर ध्यान दें:

  • प्रत्येक लेन-देन एक अलग अनुक्रमणिका का उपयोग करके एक ही पंक्ति का पता लगाता है
  • अपडेट के परिणामस्वरूप पहले से संग्रहीत डेटा में कोई परिवर्तन नहीं होता है
  • दो लेन-देन पंक्ति में अलग-अलग कॉलम 'अपडेट' करते हैं।

इन सबके बावजूद, जब पहला लेन-देन करता है तो दूसरा लेन-देन एक अद्यतन विरोध त्रुटि के साथ समाप्त हो जाता है:

सारांश:संघर्ष का पता लगाना हमेशा एक पूरी पंक्ति के स्तर पर काम करता है, और एक 'अपडेट' को वास्तव में किसी भी डेटा को बदलने की आवश्यकता नहीं होती है। (यदि आप सोच रहे थे, तो ऑफ-रो LOB या SLOB डेटा में परिवर्तन भी विरोध का पता लगाने के उद्देश्य से पंक्ति में बदलाव के रूप में गिना जाता है)।

विदेशी कुंजी समस्या

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

इसे प्रदर्शित करने के लिए, पहले निम्न तालिकाएँ और नमूना डेटा बनाएँ:

CREATE TABLE dbo.Dummy
(
    x integer NULL
);
 
CREATE TABLE dbo.Parent
(
    ParentID integer PRIMARY KEY,
    ParentValue integer NOT NULL
);
 
CREATE TABLE dbo.Child 
(
    ChildID integer PRIMARY KEY,
    ChildValue integer NOT NULL,
    ParentID integer NULL FOREIGN KEY REFERENCES dbo.Parent
);
 
INSERT dbo.Parent 
    (ParentID, ParentValue) 
VALUES (1, 1);
 
INSERT dbo.Child 
    (ChildID, ChildValue, ParentID) 
VALUES (1, 1, 1);

टिप्पणियों में बताए अनुसार अब दो अलग-अलग कनेक्शनों से निम्नलिखित को निष्पादित करें:

-- Connection 1
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION;
SELECT COUNT_BIG(*) FROM dbo.Dummy;
 
-- Connection 2 (any isolation level)
UPDATE dbo.Parent SET ParentValue = 1 WHERE ParentID = 1;
 
-- Connection 1
UPDATE dbo.Child SET ParentID = NULL WHERE ChildID = 1;
UPDATE dbo.Child SET ParentID = 1 WHERE ChildID = 1;

स्नैपशॉट लेनदेन आधिकारिक तौर पर शुरू हो गया है यह सुनिश्चित करने के लिए डमी टेबल से पढ़ा गया है। BEGIN TRANSACTION जारी करना ऐसा करने के लिए पर्याप्त नहीं है; हमें उपयोगकर्ता तालिका पर किसी प्रकार का डेटा एक्सेस करना होता है।

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

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

एक अनपेक्षित विरोध भी उत्पन्न हो सकता है यदि चाइल्ड टेबल में परिवर्तन एक पेरेंट पंक्ति को संदर्भित करता है जो बनाई गई . थी एक समवर्ती लेनदेन द्वारा (और स्नैपशॉट लेनदेन शुरू होने के बाद किया गया लेनदेन)।

सारांश:एक क्वेरी योजना जिसमें एक स्वचालित विदेशी कुंजी जांच शामिल है, एक विरोध त्रुटि उत्पन्न कर सकती है यदि स्नैपशॉट लेनदेन शुरू होने के बाद से संदर्भित पंक्ति में किसी भी प्रकार के संशोधन (निर्माण सहित!) का अनुभव हुआ है।

द ट्रंकेट टेबल इश्यू

एक स्नैपशॉट लेन-देन एक त्रुटि के साथ विफल हो जाएगा यदि लेन-देन शुरू होने के बाद से इसे एक्सेस करने वाली किसी भी तालिका को छोटा कर दिया गया है। यह तब भी लागू होता है, जब छोटी-सी तालिका में शुरू करने के लिए कोई पंक्तियाँ न हों, जैसा कि नीचे दी गई स्क्रिप्ट दर्शाती है:

CREATE TABLE dbo.AccessMe
(
    x integer NULL
);
 
CREATE TABLE dbo.TruncateMe
(
    x integer NULL
);
 
-- Connection 1
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION;
SELECT COUNT_BIG(*) FROM dbo.AccessMe;
 
-- Connection 2
TRUNCATE TABLE dbo.TruncateMe;
 
-- Connection 1
SELECT COUNT_BIG(*) FROM dbo.TruncateMe;

अंतिम चयन त्रुटि के साथ विफल रहता है:

मौजूदा डेटाबेस पर स्नैपशॉट अलगाव को सक्षम करने से पहले जांच करने के लिए यह एक और सूक्ष्म दुष्प्रभाव है।

अगली बार

इस श्रृंखला की अगली (और अंतिम) पोस्ट अनकमिटेड आइसोलेशन लेवल (प्यार से "नोलॉक" के रूप में जाना जाता है) के बारे में बात करेगी।

[ पूरी श्रृंखला के लिए सूचकांक देखें ]


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ट्रैपिंग लिंक्ड सर्वर त्रुटियाँ

  2. टी-एसक्यूएल डेटाटाइम डेटा प्रकार

  3. SQL दिनांक प्रारूप:इसे स्मार्ट तरीके से कैसे संभालें

  4. SQL में प्राथमिक कुंजी कैसे बनाएं

  5. स्वचालित डेटाबेस बैकअप को लागू करना और डिफ़ॉल्ट साधनों के साथ पुनर्स्थापित करना