2012-04-09 15 views
8

में डेडलॉक का पता चला है, मुझे अपने PostgreSQL डेटाबेस में पीएल/पीजीएसक्यूएल फ़ंक्शन से डेडलॉक समस्या का सामना करना पड़ रहा है। कृपया कोड ब्लॉक में SQL कथन पाएं (उदाहरण के लिए):पीएल/पीजीएसक्यूएल फ़ंक्शन

BEGIN 
UPDATE accounts SET balance = 0 WHERE acct_name like 'A%'; 
UPDATE accounts SET balance = balance + 100 WHERE acct_name like '%A'; 
EXCEPTION WHEN OTHERS THEN RAISE NOTICE SQLERRM; 
END; 

मुझे पता चला है कि इस कथन के दौरान हुई डेडलॉक चल रही थी। लेकिन मुझे यकीन नहीं है कि इस तालिका को एक ही समय में अपडेट करने का प्रयास करने वाले अन्य बयान थे (क्योंकि मुझे लॉगिंग सिस्टम में कोई नहीं मिला)।

तो, क्या यह संभव है कि इस कथन के भीतर डेडलॉक हुआ? जहां तक ​​मुझे पता है, अगर हमने BEGIN/END के साथ पूरे कथन को अवरुद्ध कर दिया है। वही लेनदेन होगा और खुद ही बंद नहीं किया जाना चाहिए।

+0

क्या आपके पास खातों पर कोई ट्रिगर है? क्या आप स्पष्ट लॉकिंग का भी उपयोग करते हैं? – strkol

+1

डिफ़ॉल्ट रूप से, एक लेनदेन अन्य लेनदेन द्वारा किए गए परिवर्तनों का निरीक्षण कर सकता है। अधिक जानकारी के लिए, PostgreSQL दस्तावेज़ से [लेनदेन अलगाव] (http://www.postgresql.org/docs/current/static/transaction-iso.html) देखें। –

+0

@strkol हाँ मेरे पास है, लेकिन उस ट्रिगर में कथन इस तालिका से संबंधित नहीं है। स्पष्ट लॉकिंग के लिए भी हाँ है। –

उत्तर

11

निश्चित रूप से कुछ अन्य प्रक्रिया समान संसाधन के लिए प्रतिस्पर्धा कर रही है। यह एक डेडलॉक की प्रकृति है। आपके जैसे फ़ंक्शन को कभी भी डेडलॉक नहीं किया जा सकता है। comment by @kgrittn below देखें, जो PostgreSQL में समेकन पर एक विशेषज्ञ है।

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

तथ्य यह है कि आप त्रुटि पकड़ते हैं पोस्टग्रेर्स को आपको पूरा विवरण देने से रोक सकता है। EXCEPTION अपने plpgsql फ़ंक्शन से ब्लॉक करें, अगर आपको डीबी लॉग में जानकारी नहीं मिलती है और पुनः प्रयास करें।

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


संस्करण 8.3 के लिए के रूप में: विचार करें नवीनतम संस्करण के उन्नयन। विशेष रूप से संस्करण 8.4 में इस सुधार के आप के लिए दिलचस्प होना चाहिए (quoting the release notes):

जब एक गतिरोध रिपोर्टिंग, में सर्वर लॉग को गतिरोध शामिल सभी प्रश्नों का पाठ रिपोर्ट (इतागाकी ताकहिरो)

इसके अलावा, संस्करण 8.3 इसके end of life in February 2013 से मिलेगा। आपको उन्नयन पर विचार करना शुरू करना चाहिए।

VACUUM से संबंधित एक डेडलॉक स्थिति fixed in 8.3.1 होनी चाहिए।

+0

मेरे पास पोस्टर 8.3.6 है। यह कथन सिर्फ उदाहरण के लिए उपयोग करें। दरअसल, मैं RAISE नोटिस के बजाय अन्य तालिका में सम्मिलित लॉग का उपयोग करता हूं। –

+0

आम तौर पर त्रुटि संदेश आपको आवश्यक जानकारी देनी चाहिए। मैंने अपने जवाब में कुछ जोड़ा। –

+0

आपकी सलाह के लिए बहुत बहुत धन्यवाद। मैं यह जानना जारी रखूंगा कि कौन सी अन्य प्रक्रियाएं इस तालिका के साथ कुछ करने की कोशिश कर रही थीं। –

-1

पोस्टग्रेएसक्यूएल में, शुरूआत का मतलब है कि आप बैच लेनदेन शुरू करते हैं।

आपका पहला अपडेट खातों के लिए पंक्तियों को लॉक करेगा WHERE acct_name like 'A%'; उन पंक्तियों को पहले अपडेट के बाद विशेष रूप से बंद कर दिया गया है।

दूसरा अपडेट अपडेट करने के लिए पहले अपडेट के समान सटीक पंक्तियों को खोलने का प्रयास करता है, क्योंकि पहले अपडेट अभी तक अभी तक प्रतिबद्ध नहीं हुआ है।

इस प्रकार दूसरा अपडेट हिट डेडलॉक रोलबैक था।

+0

पीएल/पीजीएसक्यूएल 'BEGIN' में केवल कोड ब्लॉक की शुरुआत है। सादा एसक्यूएल में 'BEGIN' /' COMMIT' के समान नहीं है। –

0

यदि आप को विशेष लॉक जारी करने के लिए जोड़ते हैं, तो आपको डेडलॉक समस्या नहीं मिलेगी।

BEGIN 
UPDATE accounts SET balance = 0 WHERE acct_name like 'A%'; 
COMMIT; 
UPDATE accounts SET balance = balance + 100 WHERE acct_name like '%A'; 
EXCEPTION WHEN OTHERS THEN RAISE NOTICE SQLERRM; 
END; 
+1

एकल लेनदेन प्रतिबद्ध ब्लॉक में plpgsql चलाने में प्रक्रिया, इसलिए प्रक्रियाओं में कोई प्रतिबद्धता नहीं है। – sharafjaffri