मेरे मुख्य उत्पादन आरएसी डेटाबेस पर, मुझे धीमेपन की अवधि दिखाई देती है और प्रमुख प्रतीक्षा घटना, सिस्टम चौड़ा, "कर्सर:पिन एस एक्स पर प्रतीक्षा करें" है। घटना आती है और चली जाती है, लेकिन मैं इसे समय-समय पर देखता हूं। इसलिए मुझे इसकी तह तक जाने की जरूरत थी। ध्यान दें, कि यह RAC समस्या नहीं है। इस घटना को एकल-आवृत्ति डेटाबेस पर भी आसानी से देखा जा सकता है। जब मैं इसे अपने Oracle RAC डेटाबेस के कई उदाहरणों पर देखता हूं, तो ऐसा इसलिए होता है क्योंकि मेरे पास एक ही एप्लिकेशन से कई सत्र होते हैं, सभी एक ही काम करते हैं, इस प्रकार सभी को एक ही समस्या होती है।
सबसे पहले, प्रतीक्षा घटना क्या है? कोई भी "कर्सर:" प्रतीक्षा SQL क्षेत्र में साझा पूल में अड़चनें हैं। बहुत समय पहले, साझा पूल के इस हिस्से को कुंडी द्वारा संरक्षित किया गया था। लेकिन जैसा कि साझा पूल के कई क्षेत्रों में होता है, Oracle अब म्यूटेक्स का उपयोग कर रहा है। सुरक्षा तंत्र में बदलाव के साथ, अब हमारे पास नए प्रतीक्षा कार्यक्रम हैं।
इस विशेष प्रतीक्षा घटना के मामले में, हमारे पास एक कर्सर है जो एक साझा पिन चाहता है, लेकिन अपने विशिष्ट म्यूटेक्स को जारी करने के लिए दूसरे सत्र की प्रतीक्षा करनी चाहिए। एक कर्सर पार्स करने का प्रयास कर रहा है। लेकिन इसे पार्स नहीं किया जा सकता क्योंकि एक और सत्र उसी म्यूटेक्स पर चल रहा है।
इस ईवेंट पर प्रतीक्षारत सत्रों के तीन मुख्य कारण हैं।
- उच्च हार्ड पार्स
- SQL कथन के बहुत सारे संस्करण
- बग
दुर्भाग्य से, इस प्रतीक्षा घटना से संबंधित कई बग हैं। मैंने जो देखा है उनमें से अधिकांश 11.2.0.4 या 12.1.0.1 में तय हैं, इसलिए यदि आप संस्करणों में पिछड़ रहे हैं, तो ओरेकल के नवीनतम संस्करणों में से एक में अपग्रेड करने पर विचार करें।
तो आइए देखें कि क्या हम समस्या के कारण को निर्धारित करने के लिए एक उदाहरण के माध्यम से चल सकते हैं। ऐसा करने के लिए, मैंने निम्नलिखित क्वेरी का उपयोग किया:
select s.inst_id as inst, s.sid as blocked_sid, s.username as blocked_user, sa.sql_id as blocked_sql_id, trunc(s.p2/4294967296) as blocking_sid, b.username as blocking_user, b.sql_id as blocking_sql_id from gv$session s join gv$sqlarea sa on sa.hash_value = s.p1 join gv$session b on trunc(s.p2/4294967296)=b.sid and s.inst_id=b.inst_id join gv$sqlarea sa2 on b.sql_id=sa2.sql_id where s.event='cursor: pin S wait on X';
इसे मेरे उत्पादन आरएसी डेटाबेस में से एक में चलाने पर, मुझे निम्न आउटपुट मिलता है:
INST BLOCKED_SID BLOCKED_USER BLOCKED_SQL_ID BLOCKING_SID BLOCKING_USER BLOCKING_SQL_ID ---- ----------- ------------ -------------- ------------ ------------- --------------- 4 723 USER12345 cn7m7t6y5h77g 1226 USER12345 cn7m7t6y5h77g 4 723 USER12345 cn7m7t6y5h77g 1226 USER12345 cn7m7t6y5h77g 4 723 USER12345 cn7m7t6y5h77g 1226 USER12345 cn7m7t6y5h77g 4 723 USER12345 cn7m7t6y5h77g 1226 USER12345 cn7m7t6y5h77g 4 1226 USER12345 cn7m7t6y5h77g 1796 USER12345 cn7m7t6y5h77g 4 1226 USER12345 cn7m7t6y5h77g 1796 USER12345 cn7m7t6y5h77g 4 1226 USER12345 cn7m7t6y5h77g 1796 USER12345 cn7m7t6y5h77g 4 1226 USER12345 cn7m7t6y5h77g 1796 USER12345 cn7m7t6y5h77g
ध्यान देने वाली पहली बात यह है कि ओरेकल आरएसी डेटाबेस के लिए म्यूटेक्स केवल उस उदाहरण के भीतर है। एकल-आवृत्ति डेटाबेस के लिए, ऊपर दी गई क्वेरी अभी भी काम करेगी। Oracle RAC के लिए, इस क्वेरी का आउटपुट दिखाएगा कि किस इंस्टेंस में समस्या है।
ऊपर के उदाहरण में, हमारे पास सत्र 723 सत्र 1226 द्वारा अवरुद्ध है। सत्र 1226 सत्र 1796 द्वारा आगे अवरुद्ध है। ध्यान दें कि सभी तीन सत्र SQL आईडी के साथ एक ही क्वेरी जारी कर रहे हैं cn7m7t6y5h77g ।
अब जब हम SQL आईडी जानते हैं, तो हम समस्या में शामिल SQL कथन को निर्धारित करने के लिए आसानी से V$SQL को क्वेरी कर सकते हैं। अधिक जानकारी प्राप्त करने के लिए मैंने इस क्वेरी का उपयोग किया।
select sql_id,loaded_versions,executions,loads,invalidations,parse_calls from gv$sql where inst_id=4 and sql_id='cn7m7t6y5h77g';
V$SQL को क्वेरी करने का आउटपुट इस प्रकार है:
SQL_ID LOADED_VERSIONS EXECUTIONS LOADS INVALIDATIONS PARSE_CALLS ------------- --------------- ---------- ---------- ------------- ----------- cn7m7t6y5h77g 1 105 546 308 3513
अब हम देख सकते हैं कि इस क्वेरी का SQL क्षेत्र में केवल 1 संस्करण है। तो तुरंत, हमने संभावित समस्या क्षेत्रों में से एक को समाप्त कर दिया है। भविष्य के ब्लॉग पोस्ट में, मैं SQL क्षेत्र में बड़ी संख्या में संस्करणों के साथ प्रश्नों पर चर्चा करूंगा। लेकिन आज यह हमारी समस्या नहीं है इसलिए हम आगे बढ़ते हैं।
ऊपर से यह स्पष्ट होना चाहिए कि बहुत अधिक संख्या में पार्स कॉल हैं। क्वेरी को केवल 105 बार निष्पादित किया गया है लेकिन 3513 बार पार्स किया गया है। ओह! उच्च संख्या यदि अमान्यता का शायद इससे भी कुछ लेना-देना है।
इस उदाहरण में, अब हमारे पास एक अच्छा विचार है कि समस्या क्या है। यह एक आवेदन मुद्दा है। एप्लिकेशन क्वेरी को ओवर-पार्स कर रहा है। इसलिए हम इसे वापस विकास के लिए भेजेंगे और एप्लिकेशन कोड में खुदाई करेंगे। ओवर-पार्सिंग के सामान्य कारणों की जांच करने की आवश्यकता है।
यदि संस्करणों की संख्या कम थी और अत्यधिक पार्सिंग/अमान्यता/लोड कोई समस्या नहीं थी, तो मुझे एक बग पर संदेह होगा और Oracle समर्थन के साथ एक SR फ़ाइल करेगा।