ORA-00054: संसाधन व्यस्त और NowAIT निर्दिष्ट या समय समाप्त होने के साथ अधिग्रहण


193

जब मैं टेबल अपडेट करता हूं तो मुझे यह डेटाबेस त्रुटि क्यों हो रही है?

पंक्ति 1 पर त्रुटि: ORA-00054: संसाधन व्यस्त और NowAIT निर्दिष्ट या समय समाप्त होने के साथ अधिग्रहण


22
यह आमतौर पर मदद करता है यदि आप उस कथन को पोस्ट करते हैं जो त्रुटि की ओर ले जाता है
गैरी मायर्स

जवाबों:


222

आपकी तालिका पहले से ही कुछ क्वेरी द्वारा लॉक है। उदाहरण के लिए, आपने "अपडेट के लिए चयन" निष्पादित किया हो सकता है और अभी तक कोई अन्य क्वेरी चयनित नहीं की / रोलबैक किया और निकाल दिया। अपनी क्वेरी निष्पादित करने से पहले एक कमिट / रोलबैक करें।


47
मैं इसमें एक और सत्र जोड़ूंगा। एक सामान्य परिदृश्य यह है कि आपने एक टूल में अपडेट का परीक्षण किया है, SQL डेवलपर या टॉड कहते हैं, और फिर इसे कहीं और चलाने की कोशिश की है जबकि पहला सत्र अभी भी लॉक रखता है। इसलिए आपको अपडेट को फिर से चलाने से पहले दूसरे सत्र को कमिट / रोलबैक करना होगा।
एलेक्स पोले

1
बहुधा DML (सम्मिलित / हटा / अद्यतन) एक प्रश्न के बजाय। और दूसरे सत्र में। सिर्फ इसलिए कि जिस व्यक्ति ने पूछा है वह नौसिखिया लगता है कि उत्तर सही हो सकता है। लेकिन आप उत्पादन प्रणाली में अन्य उपयोगकर्ताओं की ओर से नहीं कर सकते।
आर्टुरो हर्नान्डेज

4
ठीक है, मुझे क्या समस्या है कि टॉड में था: एक सहकर्मी उसी तालिका में था जब मैं एक पंक्ति को हटाना चाहता था, और इसलिए मैं इसे हटा नहीं सका। जब वह दूसरी तालिका में जाता है तो मैं पंक्तियों को हटाने में सक्षम था। यह शायद वहाँ किसी की मदद करे। लेकिन यह केवल तभी है जब आप तालिकाओं के अंदर टॉड के साथ काम करते हैं, और क्वेरी के लिए नहीं।
डेट्रिड

हाल ही में हमारे मंचन सर्वर (WebSphere पर स्प्रिंग अनुप्रयोग) पर हुआ। समाधान "मोनोलिथिक" डेटाबेस अपडेट स्क्रिप्ट को छोटे टुकड़ों में अलग-अलग अपडेट सेवा में एक अलग लेन-देन सेवा का उपयोग करके अलग-अलग लेन-देन को अलग करने के लिए था, जो कि एक अलग लेनदेन का उपयोग करता है:
@Transactional

102

यहां से ORA-00054: संसाधन व्यस्त और NowAIT के साथ अधिग्रहण

आप sql, उपयोगकर्ता नाम, मशीन, पोर्ट जानकारी भी देख सकते हैं और वास्तविक प्रक्रिया से जुड़ सकते हैं जो कनेक्शन रखती है

SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM,S.USERNAME,
S.MACHINE,S.PORT , S.LOGON_TIME,SQ.SQL_FULLTEXT 
FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S, 
V$PROCESS P, V$SQL SQ 
WHERE L.OBJECT_ID = O.OBJECT_ID 
AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR 
AND S.SQL_ADDRESS = SQ.ADDRESS;

5
मुझे क्वेरी से s.port को हटाना था लेकिन उसने मुझे अपराधी को ढूंढने दिया
Sibster

ताले क्षणिक हैं। इसलिए यदि इंसर्ट आता है, तो आप तुरंत प्रतिबद्ध हैं। यह इस क्वेरी में दिखाई नहीं देगा। यदि आप 'DDL' जारी करते हैं तो भी आपको त्रुटि मिल सकती है। जबकि लेन-देन खुला है। नीचे मेरी पोस्ट देखें। यह वास्तव में काम करना आसान है।
बॉब

4
मुझे ओपी जैसी ही समस्या हो रही है, लेकिन मैं आपके द्वारा उल्लिखित तालिकाओं में से किसी का भी चयन नहीं कर सकता (V $ LOCKED_OBJECT से चयन करें), उदाहरण के लिए, ORA-00942 लौटाता है: तालिका या दृश्य मौजूद नहीं है)। कोई विचार?
random_forest_fanatic

3
प्रबंधन के विचारों को देखने के लिए आपके पास पर्याप्त विशेषाधिकार नहीं हो सकते हैं।
njplumridge 15

S.Portसमस्या के अनुवर्ती : 11.2 डॉक्स Portमें एक क्षेत्र के रूप में उल्लेख किया गया है V$Session, लेकिन मेरे लिए, 11.1 का उपयोग S.Portकरना अमान्य है। क्या इसे 11.2 के लिए जोड़ा गया था, हो सकता है?

63

कृपया Oracle सत्र को मारें

सक्रिय सत्र जानकारी की जाँच करने के लिए क्वेरी के नीचे का उपयोग करें

SELECT
    O.OBJECT_NAME,
    S.SID,
    S.SERIAL#,
    P.SPID,
    S.PROGRAM,
    SQ.SQL_FULLTEXT,
    S.LOGON_TIME
FROM
    V$LOCKED_OBJECT L,
    DBA_OBJECTS O,
    V$SESSION S,
    V$PROCESS P,
    V$SQL SQ
WHERE
    L.OBJECT_ID = O.OBJECT_ID
    AND L.SESSION_ID = S.SID
    AND S.PADDR = P.ADDR
    AND S.SQL_ADDRESS = SQ.ADDRESS;

जैसे मारना

alter system kill session 'SID,SERIAL#';

(उदाहरण के लिए alter system kill session '13,36543';)

संदर्भ http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html


5
क्या विशेषाधिकारों की आवश्यकता है, इस उत्तर को स्पष्ट करना चाहिए। मेरे पास CONNECTऔर है RESOURCE, लेकिन मेरे पास जो भी खाता है, उसकी जरूरत नहीं है, और कहता है ORA-00942: table or view does not exist। इस धागे को पढ़ने वाले सभी के पास SYSखाता नहीं होगा।
vapcguy

यदि आप चयनित कॉलम 'S.OSUSER' जोड़ते हैं, तो आपको पता चल जाएगा कि कौन सा उपयोगकर्ता उस लेनदेन को चला रहा था और यदि आप सत्र को मारने से पहले उपयोगकर्ता के साथ जांच करना चाहते हैं तो यह आसान होगा।
नरसिंह

यदि सत्र लटका हुआ है, तो alter system kill session '13,36543'समय समाप्त हो जाएगा और सत्र मर नहीं जाएगा। उस मामले में देखें: stackoverflow.com/a/24306610/587365
एंड्रयू स्पेन्सर

का उपयोग कर एक मेज पर डेटा डालने जबकि एक connection objectमें pythonमैं कुछ त्रुटि मिली। फिर python scriptठीक से बंद किए बिना बंद कर दिया जाता है connection object। जब मैं दूसरे सत्र में तालिका को छोड़ने का प्रयास करता हूं तो मुझे "LOCKWAIT" त्रुटि मिल रही है। जब मैं कोशिश करता kill sessionहूं तो मेरे पास पर्याप्त निजीकरण नहीं है। इससे छुटकारा पाने के लिए और क्या किया जा सकता है?
sjd

17

इस समस्या के लिए आस-पास बहुत आसान काम है।

यदि आप अपने सत्र पर 10046 ट्रेस चलाते हैं (यह समझाने के लिए बहुत अधिक ...)। आप देखेंगे कि किसी भी DDL ऑपरेशन से पहले Oracle निम्नलिखित कार्य करता है:

LOCK TABLE 'TABLE_NAME' NO WAIT

इसलिए यदि किसी अन्य सत्र में एक खुला लेनदेन होता है तो आपको एक त्रुटि मिलती है। तो तय है ... ड्रम रोल कृपया। DDL से पहले अपना स्वयं का लॉक जारी करें और 'NO WAIT' छोड़ दें।

विशेष लेख:

यदि आप विभाजन को विभाजित कर रहे हैं / विभाजन कर रहे हैं तो विभाजन को बंद कर देता है। - तो यो विभाजन विभाजन को बंद कर सकता है।

इसलिए ... निम्नलिखित चरण समस्या को ठीक करते हैं।

  1. लॉक टेबल 'टेबल नाम'; - आप 'प्रतीक्षा' करेंगे (डेवलपर्स इसे फांसी कहते हैं)। खुले लेनदेन के साथ सत्र शुरू होने तक। यह एक कतार है। इसलिए आपके आगे कई सत्र हो सकते हैं। लेकिन आप त्रुटि नहीं करेंगे।
  2. डीडीएल निष्पादित करें। आपका DDL फिर NO WAIT के साथ एक लॉक चलाएगा। हालाँकि, आपके सत्र ने ताला खोल दिया है। तो आप अच्छे हैं।
  3. डीडीएल ऑटो-कमिट करता है। यह ताले को मुक्त करता है।

डीएमएल स्टेटमेंट 'प्रतीक्षा' करेगा या जैसा कि टेबल लॉक होने के दौरान डेवलपर्स इसे 'हैंग' कहते हैं।

मैं इसका उपयोग कोड में करता हूं जो विभाजन छोड़ने के लिए नौकरी से चलता है। यह बढ़िया काम करता है। यह एक डेटाबेस में है जो लगातार कई सौ आवेषण / सेकंड की दर से सम्मिलित कर रहा है। त्रुटियाँ नहीं।

अगर आप सोच रहे हैं। ऐसा करने से 11 ग्रा। मैंने पहले भी 10 जी में ऐसा किया है।


3
ठीक है, यह गलत है। 11g में, set_ddl_timeout का उपयोग करें, यह केवल 11g में उपलब्ध है। oracle DDL करने से पहले एक कमिट करता है, इसलिए यह लॉक को रिलीज़ करता है। 11 जी में, आप अपने डीडीएल प्रतीक्षा कर सकते हैं। मैं अब वही कर रहा हूं। ठीक काम करता है।
बॉब

3
11g में आपको EXCLUSIVE MODE में LOCK TABLE table_name का उपयोग करना चाहिए;
कामिल रोमन

1
यदि आप ORA-00054 बैच की नौकरियों से प्राप्त कर रहे हैं, तो यह वास्तव में उपयोगी है, लेकिन मुझे संदेह है कि अधिकांश लोग यहां उतर रहे हैं (ओपी सहित, और मुझे) कुछ विकास कर रहे हैं और एक सत्र को उसी मेज पर आवेषण खुला छोड़ दिया है ' फिर से गिराने और बहलाने की कोशिश कर रहा है। KILL SESSIONइन लोगों के लिए सही उत्तर है।
एंड्रयू स्पेंसर

@ याकूब कोड 11g और पुराने तरीके दोनों के लिए अच्छा होगा। इसके लिए वाक्य रचना क्या है set_ddl_timeoutऔर यह क्या होना चाहिए?
vapcguy

1
@vapcguy ने 11g पर मेरे लिए यह काम किया: डॉक्सALTER SYSTEM SET ddl_lock_timeout=20; देखें
rshdev

13

यह त्रुटि तब होती है जब संसाधन व्यस्त होता है। जाँच करें कि क्या आपके पास क्वेरी में कोई संदर्भ संबंधी बाधाएँ हैं। या यहां तक ​​कि आपके द्वारा क्वेरी में उल्लिखित तालिकाएं व्यस्त हो सकती हैं। वे कुछ अन्य नौकरी से जुड़े हो सकते हैं जो निश्चित रूप से निम्नलिखित क्वेरी परिणामों में सूचीबद्ध होंगे:

SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'

SID ढूँढें,

SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id

1
सभी को इन विचारों तक पहुंच नहीं होगी। मुझे मिलता है ORA-00942: table or view does not exist
vapcguy

ऐसे मामलों में, DB Admins उन सूचनाओं को प्रदान करने के लिए जिम्मेदार होते हैं।
अरुचुनिवेन्दन

हर बार नहीं। मुझे यह पता लगाने की कोशिश करनी थी कि यह कैसे होगा और इसके आसपास काम करना होगा और न तो मेरे और न ही मेरे सेवा खाते के पास ये अधिकार होंगे।
वाप्गुगी

7

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

यदि आपके पास SQL ​​व्यवस्थापक सिस्टम तक पहुंच है, तो इसका उपयोग आपत्तिजनक सत्र खोजने के लिए कर सकते हैं। और शायद इसे मार दें।

आप v $ सत्र और v $ लॉक और अन्य का उपयोग कर सकते हैं, लेकिन मैं आपको सुझाव देता हूं कि उस सत्र को कैसे खोजना है और फिर इसे कैसे मारना है।

एक उत्पादन प्रणाली में, यह वास्तव में निर्भर करता है। Org 10g और पुराने के लिए, आप निष्पादित कर सकते हैं

LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);

एक अलग सत्र में, लेकिन निम्नलिखित मामले में तैयार होने में बहुत लंबा समय लगता है।

alter system kill session '....

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

संस्करण 11 जी में एक नया पर्यावरण चर है जो प्रतीक्षा समय निर्धारित करता है। मुझे लगता है कि यह संभव है कि जैसा मैंने वर्णित किया है वैसा ही कुछ हो। ध्यान रहे कि लॉकिंग मुद्दे दूर नहीं जाते हैं।

ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);

अंत में इस तरह के रखरखाव के लिए सिस्टम में कुछ उपयोगकर्ता होने तक इंतजार करना सबसे अच्छा हो सकता है।


और alter system kill session '....यदि आप प्रबंधन के विचारों तक पहुंच नहीं रखते हैं , तो आप सत्र को कैसे मार सकते हैं?
vapcguy

यह मैं नहीं जानता।
आर्टुरो हर्नान्डेज

7

मेरे मामले में, मुझे पूरा यकीन था कि यह मेरे अपने सत्रों में से एक था जो अवरुद्ध था। इसलिए, निम्न कार्य करना सुरक्षित था:

  • मुझे इसके साथ अपमानजनक सत्र मिला:

    SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';

    सत्र निष्क्रिय था , लेकिन फिर भी इसने किसी तरह ताला बंद कर दिया। ध्यान दें, यदि आप कुछ अन्य उपयोग करना पड़ सकता है कि जहां आपके मामले में हालत (जैसे की कोशिश USERNAMEया MACHINEक्षेत्रों)।

  • सत्र का उपयोग करते हुए IDऔर SERIAL#ऊपर प्राप्त किया गया:

    alter system kill session '<id>, <serial#>';

@Thermz द्वारा संपादित: यदि पिछले खुले सत्र में से कोई भी काम नहीं करता है, तो यह प्रयास करें। सत्र की हत्या करते समय यह क्वेरी आपको सिंटैक्स त्रुटियों से बचने में मदद कर सकती है:

  • SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'

यदि पिछले ओपन-सत्र क्वेरी में से कोई भी काम नहीं करता है तो यह प्रयास करें।
थर्मज

5

बस सत्र को पकड़ने की प्रक्रिया की जाँच करें और इसे मार दें। वापस सामान्य करने के लिए।

एसक्यूएल के नीचे आपकी प्रक्रिया मिलेगी

SELECT s.inst_id,
   s.sid,
   s.serial#,
   p.spid,
   s.username,
   s.program FROM   gv$session s
   JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id;

फिर इसे मार डालो

ALTER SYSTEM KILL SESSION 'sid,serial#'

या

कुछ उदाहरण जो मुझे ऑनलाइन मिले हैं, उदाहरण के लिए आईडी आईडी के साथ-साथ सिस्टम किल सेशन '130,620, @ 1' की जरूरत है;


4

आपकी समस्या यह लगती है कि आप DML और DDL संचालन को मिला रहे हैं। यह URL देखें जो इस समस्या की व्याख्या करता है:

http://www.orafaq.com/forum/t/54714/2/



3

मैं केवल एक टेबल बनाते समय इस त्रुटि को मारने में कामयाब रहा! एक मेज पर स्पष्ट रूप से कोई विवाद की समस्या नहीं थी जो अभी तक मौजूद नहीं थी। CREATE TABLEबयान एक निहित CONSTRAINT fk_name FOREIGN KEYएक अच्छी तरह से आबादी वाले तालिका संदर्भित खंड। मुझे करना पड़ा:

  • FORATEIGN KEY क्लॉज को CREATE TABLE स्टेटमेंट से हटा दें
  • FK कॉलम पर एक INDEX बनाएं
  • एफके बनाएं

मुझे बस यही समस्या थी। मैंने ddl स्टेटमेंट से fk परिभाषा को हटाने के बाद तालिका बनाने में सक्षम था, लेकिन कॉलम पर इंडेक्स बनाने के बाद भी मैं इसे जोड़ नहीं पा रहा हूं।
vadipp

मैं इसे हल करने में सक्षम था। सबसे पहले, मैंने एक novalidateखंड जोड़ा alter table add constraint। यह किसी तरह इसे चलाने देता है, लेकिन यह लॉक हो जाता है। फिर मैंने सत्र के ताले को देखा कि यह किस सत्र में बंद है। और फिर मैंने उस सत्र को मार दिया।
vadipp

3

मुझे यह त्रुटि तब हुई जब मेरे पास 2 स्क्रिप्ट थीं जो मैं चला रहा था। मैं था:

  • एक SQL * प्लस सत्र एक स्कीमा उपयोगकर्ता खाते (खाता # 1) का उपयोग करके सीधे जुड़ा हुआ है
  • एक और एसक्यूएल * प्लस सत्र एक अलग स्कीमा उपयोगकर्ता खाते (खाता # 2) का उपयोग करके जुड़ा हुआ है, लेकिन पहले खाते के रूप में एक डेटाबेस लिंक से जुड़ रहा है

मैंने टेबल ड्रॉप चलाया, फिर खाता # 1 के रूप में टेबल क्रिएट किया। मैंने # 2 के सत्र में एक टेबल अपडेट चलाया। बदलाव नहीं किया। खाता # 1 के रूप में तालिका ड्रॉप / निर्माण स्क्रिप्ट को फिर से चलाया। drop table xकमांड पर त्रुटि हुई ।

मैंने इसे COMMIT;खाता * 2 के SQL * प्लस सत्र में चलाकर हल किया ।


यदि आपके पास टेबल छोड़ने की अनुमति नहीं है तो आप क्या करेंगे? बुरा जवाब
शकीर हुसैन

1
शकर, यह केवल एक उदाहरण था कि मैं क्या कर रहा था जब यह मेरे साथ हुआ था - समस्या का समाधान नहीं - जो कि मेरी बहुत अंतिम पंक्ति में था - एक चल रहा था COMMIT;। यदि आप एक तालिका भी नहीं छोड़ सकते हैं, तो आपके पास ऐसी कोई भी चीज़ को बदलने की अनुमति नहीं है जो आपको इस मुद्दे पर पहली बार में आएगी।
vapcguy

-2

मैं भी इसी तरह के मुद्दे का सामना करता हूं। इस त्रुटि को हल करने के लिए कुछ भी प्रोग्रामर को नहीं करना है। मैंने अपने ओरेकल डीबीए टीम को सूचित किया। उन्होंने सत्र को मार दिया और एक आकर्षण की तरह काम किया।


1
अभी भी किसी को कुछ करना है। यदि DBA टीम को पता नहीं है कि क्या करना है, और एक सत्र को कैसे मारना है? बुरा जवाब।
vapcguy

1
यदि DBA को सत्र को मारने का तरीका नहीं पता है, तो वह काम करने के लिए अयोग्य है
Shakeer Hussain

गलत होने से बचने के लिए समय-समय पर सभी को सिंटैक्स पर रिफ्रेशर की जरूरत होती है।
vapcguy

-5

शशि के लिंक द्वारा दिया गया समाधान सबसे अच्छा है ... dba या किसी और से संपर्क करने की आवश्यकता नहीं है

एक बैकअप बनाओ

create table xxxx_backup as select * from xxxx;

सभी पंक्तियों को हटा दें

delete from xxxx;
commit;

अपना बैकअप डालें।

insert into xxxx (select * from xxxx_backup);
commit;

10
हटाएं / हटाएं विनिमेय नहीं हैं। बड़ी संख्या में डिलीट करने से बड़े पैमाने पर प्रदर्शन निहितार्थ होते हैं। यह वास्तव में बुरा है।
बॉब

मुझे लगा कि यह एक सामान्य पैटर्न है।
शॉन Xue
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.