क्या किसी पोस्टग्रेएसक्यूएल टेरर क्वेरी को रद्द करना सुरक्षित है जो लॉक पर प्रतीक्षा कर रहा है?


10

हमने ALTER TABLEघंटों पहले एक क्वेरी शुरू की थी और केवल हाल ही में (के माध्यम से pg_stat_activity) एहसास हुआ कि यह एक लॉक पर प्रतीक्षा कर रहा है। हमने उस दूसरी क्वेरी की खोज की, जिसे हम उस तालिका में बंद करना चाहते हैं जिसे हम बदलना चाहते हैं, और उसे जाने नहीं दे रहे हैं।

हमारी क्वेरी एक "सरल" क्वेरी है (एक कॉलम डेटा प्रकार बदल रहा है), लेकिन यह एक विशाल तालिका पर चल रहा है।

ताला पर जो प्रक्रिया चल रही है, उसे मारने के बजाय, हमने तय किया है कि हम इसे मार डालेंगे ALTER TABLE

हमने लेन-देन में लपेट नहीं किया ALTER TABLE

जहां तक ​​मैं समझता हूं, यह तथ्य कि हमारी क्वेरी लॉक का इंतजार कर रही है, इसका मतलब है कि यह हमेशा लॉक का इंतजार करता रहा है, और इसने कभी भी कुछ भी नहीं बदला है।

क्या ये सच है? क्या हमारे लिए अपनी ALTER TABLEक्वेरी को एकमुश्त रद्द करना सुरक्षित है ? या क्या यह संभव है कि क्वेरी पहले से ही कुछ संशोधित कर चुकी है और इसे रद्द करने से हमारा डेटाबेस किसी तरह से आधे रास्ते में चला जाएगा?

पुनश्च: योजना का उपयोग कर इसे रद्द करना है SELECT pg_cancel_backend(pid);। यदि यह एक बुरा विचार है, तो कृपया मुझे बताएं।


1
अलर्ट को रद्द करने के लिए ठीक होना चाहिए। PostgreSQL में ट्रांजेक्शनल डीडीएल है, और आपको उसी स्थिति में छोड़ दिया जाना चाहिए जैसे कि आपने ALTER TABLE को बिल्कुल नहीं चलाया है।
जोश कुपरश्मिद्ट

इसलिए जब आप कहते हैं कि PostgreSQL का एक लेनदेन DDL है, तो क्या इसका मतलब यह है कि किसी भी स्कीमा-बदलते क्वेरी को अनिवार्य रूप से लेनदेन के अंदर चलाया जाता है?
19

1
आपके मामले में, ALTER TABLE "अनिवार्य रूप से लेन-देन के अंदर चला गया" है, क्योंकि आपने कहा था "हमने लेनदेन में ALTER TABLE को लपेटा नहीं था।" यदि आप हालांकि चाहते थे, तो आप BEGIN लिख सकते थे; टेटर टेबल फू ...; टेटर टेबल बार ...; आदि। ; COMMIT; - यह Transgional DDL वाले PostgreSQL की वास्तविक हत्यारा सुविधा है। लेकिन आपकी तात्कालिक स्थिति के लिए, हाँ, अपने दम पर पहले से ही सुरक्षित रूप से रद्द किया जा सकता है और लुढ़का हुआ वापस आ जाएगा जैसे कि यह कभी नहीं हुआ।
जोश कुपर्शमीद

आपके त्वरित उत्तरों के लिए बहुत बहुत धन्यवाद! यह बहुत अच्छी जानकारी है। क्या आप इसे उत्तर के रूप में पोस्ट कर सकते हैं ताकि मैं इसे स्वीकार कर सकूं?
JMTyler

जवाबों:


13

जहां तक ​​मैं समझता हूं, यह तथ्य कि हमारी क्वेरी लॉक का इंतजार कर रही है, इसका मतलब है कि यह हमेशा लॉक का इंतजार करता रहा है, और इसने कभी भी कुछ भी नहीं बदला है।

सही - अगर आप देखते हैं कि pg_stat_activity.waiting एक ALABLE टेबल के लिए "सत्य" है, तो इसका लगभग निश्चित रूप से मतलब है कि यह धैर्यपूर्वक अपने लक्ष्य तालिका पर ACCESS EXCLUSIVE लॉक की प्रतीक्षा कर रहा है, और इसके वास्तविक कार्य (यदि आवश्यक हो तो तालिका को फिर से लिखना, कैटलॉग बदलना) , पुनर्निर्माण अनुक्रमित, आदि) अभी तक शुरू नहीं हुआ है।

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

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

आपने यह भी देखा होगा कि PostgreSQL में, एक (बहु-स्टेटमेंट) लेनदेन के अंदर नेस्टेड डीडीएल कमांड का प्रदर्शन करना संभव है।

BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind

(यह सुनिश्चित करने के लिए कि स्कीमा माइग्रेशन सभी में एक साथ या बिल्कुल नहीं चलते हैं।) आपने कहा, हालांकि:

हमने लेन-देन में लपेट नहीं किया ALTER TABLE

यह एक आदेश के लिए ठीक है - डॉक्स से ,

PostgreSQL वास्तव में लेनदेन के भीतर निष्पादित होने के रूप में हर SQL स्टेटमेंट को मानता है। यदि आप एक BEGIN आदेश जारी नहीं करते हैं, तो प्रत्येक व्यक्ति के कथन में एक अंतर्निहित BEGIN है और (यदि सफल) COMMIT उसके चारों ओर लिपटा हुआ है। BEGIN और COMMIT द्वारा घिरे बयानों के समूह को कभी-कभी लेन-देन ब्लॉक कहा जाता है।

इस प्रकार, रद्द करने के ALTER TABLEमाध्यम से pg_cancel_backend()या तो, या एक Ctrl-C जो नियंत्रित psql प्रॉम्प्ट से जारी किया गया है, का एक समान प्रभाव होगा जैसे आपने किया था

BEGIN;
ALTER TABLE ... ;
ROLLBACK;

(यद्यपि आपको उम्मीद है कि देखने के लिए, उस महंगी ALTER TABLEको रद्द करने से डेटाबेस को अनावश्यक पीसने से बचाया जा सकता है यदि आप अभी ROLLBACKभी वैसे ही जा रहे हैं ।)


5

जोश के सही और उत्कृष्ट उत्तर के बारे में विस्तार से बताने के लिए:

क्या यह हमारे लिए सुरक्षित है कि हम अपनी वैकल्पिक क्वेरी को रद्द कर दें?

हाँ।

यह तब भी सुरक्षित होगा जब यह तालिका को फिर से लिखने के बीच में हो

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

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


3
बस के बारे में एक नोट "आप बस पूरे PostgreSQL सर्वर को बंद कर सकते हैं, या वास्तव में जिस मशीन पर यह चलता है, उसे पुनरारंभ करें, और सब कुछ ठीक होगा" - जब तक आपके पास विश्वसनीय हार्डवेयर नहीं है, तब तक बहुत सही है जो fsync के बारे में झूठ नहीं बोलता है , wiki.postgresql.org/wiki/Reliable_Writes
जोश कुपरशमीद

2
@JoshKupershmidt ज़रूर, लेकिन यह DDL के लिए विशिष्ट नहीं है। यदि आपके पास समन्‍वयन समस्‍याएं हैं तो आप हर चीज के लिए क्रैश-असुरक्षित हैं
क्रेग रिंगर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.