PostgreSQL इन-प्लेस अपडेट मैकेनिज्म का उपयोग नहीं करता है, इसलिए जिस तरह से DELETE और UPDATE कमांड को डिज़ाइन किया गया है, उसके अनुसार,
- जब भी DELETE ऑपरेशन किए जाते हैं, तो यह मौजूदा टपल को उन टुपल्स को भौतिक रूप से हटाने के बजाय DEAD के रूप में चिह्नित करता है।
- इसी तरह, जब भी UPDATE ऑपरेशन किया जाता है, तो यह संबंधित मौजूदा टपल को DEAD के रूप में चिह्नित करता है और एक नया टपल (यानी UPDATE ऑपरेशन =DELETE + INSERT) सम्मिलित करता है।
इसलिए प्रत्येक DELETE और UPDATE कमांड के परिणामस्वरूप एक DEAD टपल होगा, जिसका कभी भी उपयोग नहीं किया जाएगा (जब तक कि समानांतर लेनदेन न हों)। इन मृत टुपल्स से अनावश्यक अतिरिक्त स्थान का उपयोग होगा, भले ही प्रभावी रिकॉर्ड की संख्या समान या कम हो। इसे PostgreSQL में स्पेस ब्लोटिंग भी कहा जाता है। चूंकि PostgreSQL व्यापक रूप से OLTP प्रकार के रिलेशनल डेटाबेस सिस्टम के रूप में उपयोग किया जाता है, जहां लगातार INSERT, UPDATE और DELETE ऑपरेशन किए जाते हैं, कई DEAD टुपल्स होंगे और इसलिए संबंधित परिणाम होंगे। इसलिए PostgreSQL को इन DEAD टुपल्स से निपटने के लिए एक मजबूत रखरखाव तंत्र की आवश्यकता है। VACUUM रखरखाव प्रक्रिया है जो VACUUM संचालन को अनुकूलित करने के लिए उपयोगी कुछ और गतिविधियों के साथ-साथ DEAD टपल से निपटने का ध्यान रखती है। आइए इस ब्लॉग में बाद में उपयोग की जाने वाली कुछ शब्दावली को समझते हैं।
दृश्यता मानचित्र
जैसा कि नाम से ही स्पष्ट है, यह केवल टुपल्स वाले पृष्ठों के बारे में दृश्यता जानकारी रखता है जो सभी सक्रिय लेनदेन के लिए दृश्यमान होने के लिए जाने जाते हैं। प्रत्येक पृष्ठ के लिए, एक बिट का उपयोग किया जाता है। यदि बिट को 1 पर सेट किया जाता है, तो इसका मतलब है कि संबंधित पेज के सभी टुपल्स दिखाई दे रहे हैं। बिट को 0 पर सेट करने का मतलब है कि दिए गए पेज पर कोई खाली जगह नहीं है और टुपल्स सभी लेन-देन के लिए दृश्यमान हो सकते हैं।
दृश्यता मानचित्र प्रत्येक संबंध (तालिका और अनुक्रमणिका) के लिए बनाए रखा जाता है और मुख्य संबंधों के साथ संबद्ध हो जाता है अर्थात यदि संबंध फ़ाइल नोड नाम 12345 है, तो दृश्यता फ़ाइल समानांतर फ़ाइल 12345_vm में संग्रहीत हो जाती है।पी>
फ्री स्पेस मैप
यह रिक्त स्थान की जानकारी रखता है जिसमें संबंध में उपलब्ध स्थान के बारे में विवरण होता है। इसे रिलेशन मेन फाइल के समानांतर फाइल में भी स्टोर किया जाता है यानी अगर रिलेशन फाइल नोड नेम 12345 है, तो फ्री स्पेस मैप फाइल पैरेलल फाइल 12345_fsm में स्टोर हो जाती है।
टुपल को फ्रीज करें
PostgreSQL ट्रांजेक्शन आईडी को स्टोर करने के लिए 4 बाइट्स का उपयोग करता है, जिसका अर्थ है कि इसे लपेटने से पहले अधिकतम 2 बिलियन लेनदेन उत्पन्न किए जा सकते हैं। अब इस समय अभी भी विचार करें कि कुछ टुपल में प्रारंभिक लेनदेन आईडी 100 है, फिर नए लेनदेन के लिए (जो लेनदेन के चारों ओर लिपटे का उपयोग करता है) 5 कहें, लेनदेन आईडी 100 भविष्य में देखेगा और यह जोड़ा गया डेटा नहीं देख पाएगा / इसके द्वारा संशोधित किया गया, भले ही यह वास्तव में अतीत में था। इस विशेष लेनदेन से बचने के लिए फ्रोजनट्रांसेक्शन आईडी (2 के बराबर) असाइन की गई है। यह विशेष लेन-देन आईडी हमेशा अतीत की मानी जाती है और सभी लेन-देन के लिए दृश्यमान होगी।
VACUUM
VACUUM का प्राथमिक कार्य DEAD टुपल्स के कब्जे वाले संग्रहण स्थान को पुनः प्राप्त करना है। पुनः प्राप्त संग्रहण स्थान ऑपरेटिंग सिस्टम को वापस नहीं दिया जाता है, बल्कि वे केवल उसी पृष्ठ के भीतर डीफ़्रैग्मेन्ट किए जाते हैं, इसलिए वे उसी तालिका में भविष्य के डेटा सम्मिलन द्वारा पुन:उपयोग के लिए उपलब्ध होते हैं। जबकि VACUUM ऑपरेशन एक विशेष टेबल पर चल रहा है, साथ ही साथ अन्य रीड / राइट ऑपरेशन उसी टेबल पर किया जा सकता है क्योंकि विशेष टेबल पर एक्सक्लूसिव लॉक नहीं लिया जाता है। यदि तालिका का नाम निर्दिष्ट नहीं है, तो डेटाबेस के सभी तालिकाओं पर VACUUM किया जाएगा। VACUUM ऑपरेशन ShareUpdateExclusive लॉक के भीतर ऑपरेशन की एक श्रृंखला के नीचे प्रदर्शन करता है:
- सभी डेड टुपल्स पाने के लिए डेटाबेस के सभी टेबल (या निर्दिष्ट टेबल) के सभी पेज स्कैन करें।
- यदि आवश्यक हो तो पुराने टुपल्स को फ्रीज करें।
- संबंधित DEAD tuples की ओर इशारा करते हुए इंडेक्स टपल को हटा दें।
- किसी विशिष्ट तालिका से संबंधित पेज के डेड टुपल्स को हटा दें और पेज में लाइव टुपल्स को फिर से आवंटित करें।
- फ्री स्पेस मैप (FSM) और विजिबिलिटी मैप (VM) अपडेट करें।
- यदि संभव हो तो अंतिम पृष्ठ को छोटा करें (यदि मृत टुपल्स थे जो मुक्त हो गए थे)।
- सभी संगत सिस्टम टेबल अपडेट करें।
जैसा कि हम VACUUM के काम के उपरोक्त चरणों से देख सकते हैं, यह स्पष्ट है कि यह एक बहुत ही महंगा ऑपरेशन है क्योंकि इसे संबंध के सभी पृष्ठों को संसाधित करने की आवश्यकता है। इसलिए संभावित पृष्ठों को छोड़ना बहुत आवश्यक है, जिन्हें वैक्यूम करने की आवश्यकता नहीं है। चूंकि दृश्यता मानचित्र (वीएम) उस पृष्ठ की जानकारी देता है जहां कोई खाली स्थान नहीं है, यह माना जा सकता है कि संबंधित पृष्ठ वैक्यूम की आवश्यकता नहीं है और इसलिए इस पृष्ठ को सुरक्षित रूप से छोड़ा जा सकता है।
चूंकि VACUUM वैसे भी सभी पृष्ठों और उनके सभी टुपल्स को पार करता है, इसलिए यह क्वालिफाइंग टुपल्स को फ़्रीज़ करने के अन्य महत्वपूर्ण कार्य करने का अवसर लेता है।
पूर्ण वैक्यूम
जैसा कि पिछले अनुभाग में चर्चा की गई है, भले ही VACUUM सभी DEAD टुपल्स को हटा देता है और भविष्य में उपयोग के लिए पृष्ठ को डीफ़्रैग्मेन्ट करता है, यह तालिका के समग्र संग्रहण को कम करने में मदद नहीं करता है क्योंकि वास्तव में स्थान को जारी नहीं किया जाता है ऑपरेटिंग सिस्टम। मान लीजिए कि एक तालिका tbl1 है कि कुल संग्रहण 1.5GB तक पहुंच गया है और इस 1GB में से मृत ट्यूपल द्वारा कब्जा कर लिया गया है, तो VACUUM के बाद एक और लगभग 1GB आगे टपल सम्मिलन के लिए उपलब्ध होगा लेकिन फिर भी, कुल संग्रहण 1.5GB ही रहेगा।
पूर्ण VACUUM वास्तव में स्थान खाली करके और इसे ऑपरेटिंग सिस्टम पर वापस लौटाकर इस समस्या को हल करता है। लेकिन यह एक कीमत पर आता है। VACUUM के विपरीत, FULL VACUUM समानांतर संचालन की अनुमति नहीं देता है क्योंकि यह पूर्ण VACUUMed प्राप्त करने वाले संबंध पर एक विशेष लॉक लेता है। नीचे दिए गए चरण हैं:
- रिश्तों पर विशेष ताला लगाता है।
- एक समानांतर खाली संग्रहण फ़ाइल बनाएं।
- सभी लाइव टुपल्स को मौजूदा स्टोरेज से नए आवंटित स्टोरेज में कॉपी करें।
- फिर मूल मेमोरी खाली करें।
- लॉक को खाली करें।
इसलिए जैसा कि चरणों से भी स्पष्ट है, इसमें केवल शेष डेटा के लिए आवश्यक संग्रहण होगा।
ऑटो वैक्यूम
वैक्यूम को मैन्युअल रूप से करने के बजाय, PostgreSQL एक दानव का समर्थन करता है जो समय-समय पर स्वचालित रूप से VACUUM को ट्रिगर करता है। हर बार जब VACUUM जागता है (डिफ़ॉल्ट रूप से 1 मिनट) यह कई कार्यों को आमंत्रित करता है (कॉन्फ़िगरेशन autovacuum_worker प्रक्रियाओं के आधार पर)।
ऑटो-वैक्यूम कार्यकर्ता संबंधित निर्दिष्ट तालिकाओं के लिए VACUUM प्रक्रियाओं को समवर्ती रूप से करते हैं। चूंकि VACUUM टेबल पर कोई विशेष लॉक नहीं लेता है, यह अन्य डेटाबेस कार्य को प्रभावित नहीं करता (या न्यूनतम)।
ऑटो-वैक्यूम का विन्यास डेटाबेस के उपयोग पैटर्न के आधार पर किया जाना चाहिए। यह बहुत बार-बार नहीं होना चाहिए (क्योंकि यह कार्यकर्ता के जागने को बर्बाद कर देगा क्योंकि हो सकता है कि बहुत कम मृत ट्यूपल्स न हों) या बहुत अधिक विलंबित (यह एक साथ बहुत सारे मृत टुपल्स का कारण होगा और इसलिए टेबल ब्लोट)।
VACUUM या पूर्ण VACUUM
आदर्श रूप से, डेटाबेस एप्लिकेशन को इस तरह से डिज़ाइन किया जाना चाहिए कि पूर्ण वैक्यूम की कोई आवश्यकता न हो। जैसा कि ऊपर बताया गया है, FULL VACUUM स्टोरेज स्पेस को फिर से बनाता है और डेटा को वापस रखता है, इसलिए यदि केवल कम डेड टुपल्स हैं, तो सभी मूल डेटा को वापस रखने के लिए तुरंत स्टोरेज स्पेस को फिर से बनाया जाएगा। चूंकि FULL VACUUM टेबल पर एक्सक्लूसिव लॉक लेता है, इसलिए यह संबंधित टेबल पर सभी ऑपरेशन्स को ब्लॉक कर देता है। इसलिए FULL VACUUM करना कभी-कभी समग्र डेटाबेस को धीमा कर सकता है।
संक्षेप में पूर्ण VACUUM से बचा जाना चाहिए जब तक कि यह ज्ञात न हो कि अधिकांश संग्रहण स्थान मृत टुपल्स के कारण है। PostgreSQL एक्सटेंशन pg_freespacemap का उपयोग खाली स्थान के बारे में उचित संकेत प्राप्त करने के लिए किया जा सकता है।
आइए व्याख्या की गई VACUUM प्रक्रिया का एक उदाहरण देखते हैं।
सबसे पहले, आइए एक टेबल डेमो1 बनाएं:
postgres=# create table demo1(id int, id2 int);
CREATE TABLE
और वहां कुछ डेटा डालें:
postgres=# insert into demo1 values(generate_series(1,10000), generate_series(1,
10000));
INSERT 0 10000
postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');
npages | average_freespace_ratio
--------+-------------------------
45 | 0.00
(1 row)
अब, आइए डेटा हटाएं:
postgres=# delete from demo1 where id%2=0;
DELETE 5000
और मैन्युअल वैक्यूम चलाएं:
postgres=# vacuum demo1;
VACUUM
postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');
npages | average_freespace_ratio
--------+-------------------------
45 | 45.07
(1 row)
यह फ़्रीस्पेस अब PostgreSQL द्वारा पुन:उपयोग के लिए उपलब्ध है, लेकिन यदि आप उस स्थान को ऑपरेटिंग सिस्टम के लिए जारी करना चाहते हैं, तो चलाएँ:
postgres=# vacuum full demo1;
VACUUM
postgres=# SELECT count(*) as npages, round(100 * avg(avail)/8192 ,2) as average_freespace_ratio FROM pg_freespace('demo1');
npages | average_freespace_ratio
--------+-------------------------
23 | 0.00
(1 row)
निष्कर्ष
और यह एक छोटा सा उदाहरण था कि VACUUM प्रक्रिया कैसे काम करती है। सौभाग्य से, ऑटो वैक्यूम प्रक्रिया के लिए धन्यवाद, ज्यादातर समय और एक सामान्य PostgreSQL वातावरण में, आपको इस बारे में सोचने की आवश्यकता नहीं है क्योंकि यह इंजन द्वारा ही प्रबंधित किया जाता है।