2010-02-02 14 views
10

में कैसे को खोजने के लिए बंद कर दिया पंक्तियों हम एक Oracle डाटाबेस है, और ग्राहक के खाते तालिका पंक्तियों लाख के बारे में है। सालों से, हमने चार अलग-अलग यूआई (ओरेकल फॉर्म में दो, नेट में दो) बनाए हैं, जिनमें से सभी उपयोग में रहते हैं। हमारे पास कई पृष्ठभूमि कार्य हैं (दोनों लगातार और अनुसूचित) भी।ओरेकल

कुछ बार कभी-कभी खाता तालिका में एक पंक्ति पर एक लंबा लॉक (30 सेकंड से अधिक) कहता है, जो लगातार पृष्ठभूमि कार्यों में से एक को विफल कर देता है। प्रश्न में पृष्ठभूमि कार्य अपडेट समय के बाद खुद को पुन: प्रारंभ करता है। ऐसा होने के कुछ मिनट बाद हम इसके बारे में पता लगाते हैं, लेकिन तब तक लॉक जारी किया गया है।

हमारे पास यह मानने का कारण है कि यह एक गलत व्यवहार यूआई हो सकता है, लेकिन "धूम्रपान बंदूक" नहीं ढूंढ पा रहा है।

मैं ऐसी क्वेरी, जो ब्लॉक सूची मिल गया है, लेकिन है कि जब आप एक पंक्ति के लिए विवाद दो नौकरियां मिल गया है के लिए है। मैं जानना चाहता हूं कि कौन सी पंक्तियां ताले हैं जब लॉक पाने की कोशिश करने की दूसरी नौकरी जरूरी नहीं है।

हम 11g पर हो, लेकिन 8i के बाद से समस्या का सामना कर दिया गया है।

उत्तर

10

Oracle की लॉकिंग अवधारणा अन्य प्रणालियों की तुलना में काफी अलग है।

जब Oracle में एक पंक्ति बंद कर दिया जाता है, रिकॉर्ड ही नया मान (यदि हो तो) और इसके अलावा में, के साथ अद्यतन किया जाता है, एक ताला (जो अनिवार्य रूप से लेन-देन ताला करने के लिए एक सूचक है कि रोलबैक खंड में रहता है) रखा गया है सही रिकॉर्ड में।

इसका मतलब है कि Oracle में रिकॉर्ड लॉक करना मतलब है रिकॉर्ड का मेटाडेटा अपडेट करना और लॉजिकल पेज लिखना जारी करना। उदाहरण के लिए, आप केवल पढ़ने के लिए टेबल पर SELECT FOR UPDATE नहीं कर सकते हैं।

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

इसका मतलब है कि प्रत्येक रिकॉर्ड में लेनदेन के बारे में कुछ जानकारी होती है जो आखिरी बार अपडेट की जाती है, भले ही लेन-देन की मृत्यु हो गई हो। यह पता लगाने के लिए कि लेनदेन जिंदा है या नहीं (और, इसलिए, यदि रिकॉर्ड जिंदा है या नहीं), तो रोलबैक सेगमेंट पर जाना आवश्यक है।

ओरेकल में पारंपरिक लॉक मैनेजर नहीं है, और इसका मतलब है कि सभी ताले की एक सूची प्राप्त करने के लिए सभी ऑब्जेक्ट्स में सभी रिकॉर्ड्स स्कैन करना आवश्यक है। यह बहुत लंबा लगेगा।

आप लॉक मेटाडेटा ऑब्जेक्ट्स (v$locked_object का उपयोग करके) कुछ विशेष ताले प्राप्त कर सकते हैं, लॉक प्रतीक्षा करता है (v$session का उपयोग करके), लेकिन डेटाबेस में सभी ऑब्जेक्ट्स पर सभी ताले की सूची नहीं।

+0

नहीं कर सकते 'आप वी $ लॉक सभी ताले प्राप्त करने के लिए उपयोग करने के साथ पूछताछ की oralce में बंद टेबल मिल सकती है? यहां तक ​​कि यदि आप लॉक होने वाली विशिष्ट पंक्तियों को निर्धारित नहीं कर सकते हैं, तो कम से कम आप कौन सी टेबल जानते हैं। –

4

बजाय ताले, मैं सुझाव है कि आप लंबे समय से चल रहा है लेनदेन, v$transaction का उपयोग कर देखो। वहां से आप v$session पर शामिल हो सकते हैं, जो आपको यूआई (प्रोग्राम और मशीन कॉलम आज़माएं) के साथ-साथ उपयोगकर्ता के बारे में एक विचार देना चाहिए। dba_blockers, dba_waiters और लॉक करने के लिए dba_locks पर

4

देखो। नाम आत्म व्याख्यात्मक होना चाहिए।

आप एक नौकरी बना सकते हैं जो एक मिनट में चलता है और कहता है कि dba_blockers में मानों को लॉग करता है और उस सत्र के लिए वर्तमान सक्रिय sql_id। (वी $ सत्र और वी $ sqlstats के माध्यम से)।

तुम भी वी $ sql_monitor में देखने के लिए कर सकते हैं।यह डिफ़ॉल्ट रूप से सभी SQL को लॉग करेगा जो 5 सेकंड से अधिक समय लेता है। यह एंटरप्राइज़ मैनेजर में SQL मॉनीटरिंग पेज पर भी दिखाई देता है।

+0

'dba_blockers' और आपके द्वारा उल्लिखित अन्य विचारों में केवल ताले की प्रतीक्षा की जाएगी। @op ने निर्दिष्ट किया कि वह सभी ताले चाहता है, न कि रिकॉर्ड पर केवल उन लोगों का तर्क है। – Quassnoi

+0

लेकिन यदि कुछ भी अवरुद्ध नहीं किया जा रहा है तो एक सत्र तब तक लॉक हो सकता है जब तक यह पसंद न करे क्योंकि यह प्रदर्शन को प्रभावित नहीं करेगा। केवल ताले अवरुद्ध प्रदर्शन को प्रभावित करते हैं। – PenFold

1

आप निम्न क्वेरी

select 
    c.owner, 
    c.object_name, 
    c.object_type, 
    b.sid, 
    b.serial#, 
    b.status, 
    b.osuser, 
    b.machine 
from 
    v$locked_object a , 
    v$session b, 
    dba_objects c 
where 
    b.sid = a.session_id 
and 
    a.object_id = c.object_id;