[oracle] ORA-00054 : 자원이 바쁘고 NOWAIT가 지정되어 있거나 타임 아웃이 만료 된 취득

테이블을 업데이트 할 때이 데이터베이스 오류가 발생하는 이유는 무엇입니까?

1 행의 오류 : ORA-00054 : 자원이 사용 중이며 NOWAIT를 지정하여 획득하거나 시간 종료가 만료되었습니다



답변

테이블이 이미 일부 쿼리에 의해 잠겨 있습니다. 예를 들어 “업데이트를 위해 선택”을 실행했지만 아직 다른 선택 쿼리를 커밋 / 롤백하지 않고 시작했을 수 있습니다. 쿼리를 실행하기 전에 커밋 / 롤백을 수행하십시오.


답변

여기에서 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;


답변

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


답변

이 문제에 대한 매우 쉬운 해결 방법이 있습니다.

세션에서 10046 추적을 실행하면 (Google이 설명하기에는 너무 많습니다). DDL 작업 전에 Oracle이 다음을 수행함을 알 수 있습니다.

LOCK TABLE ‘TABLE_NAME’NO WAIT

따라서 다른 세션에 열린 트랜잭션이 있으면 오류가 발생합니다. 그래서 수정은 … 드럼 롤주세요. DDL 전에 자신의 잠금 장치를 발행하고 ‘NO WAIT’을 ​​생략하십시오.

특별 참고 사항 :

파티션 분할 / 삭제를 수행하는 경우 oracle은 파티션을 잠급니다. 따라서 파티션 하위 파티션을 잠글 수 있습니다.

그래서 … 다음 단계는 문제를 해결합니다.

  1. 잠금 테이블 ‘표 이름’; -당신은 ‘기다릴 것입니다 (개발자들은 이것을 교수형이라고 부릅니다). 열린 트랜잭션 세션이 커밋 될 때까지 이것은 대기열입니다. 그래서 몇 번의 세션이있을 수 있습니다. 그러나 오류가 발생하지 않습니다.
  2. DDL을 실행하십시오. 그런 다음 DDL은 NO WAIT로 잠금을 실행합니다. 그러나 세션이 잠금을 요청했습니다. 그래서 당신은 좋습니다.
  3. DDL 자동 커밋 잠금이 해제됩니다.

테이블이 잠겨있는 동안 DML 문은 ‘대기’하거나 개발자가이를 ‘멈춤’이라고합니다.

작업에서 실행되어 파티션을 삭제하는 코드에서 이것을 사용합니다. 잘 작동합니다. 초당 수백 번의 삽입 속도로 지속적으로 삽입되는 데이터베이스에 있습니다. 오류가 없습니다.

궁금하다면 11g에서이 작업을 수행합니다. 나는 과거에도 10g 전에 이것을했습니다.


답변

이 오류는 리소스가 사용 중일 때 발생합니다. 조회에 참조 제한 조건이 있는지 확인하십시오. 또는 쿼리에서 언급 한 테이블도 사용 중일 수 있습니다. 그들은 다음과 같은 쿼리 결과에 분명히 나열된 다른 작업과 관련이있을 수 있습니다.

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

SID를 찾으십시오.

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


답변

이것은 테이블을 변경하는 데 사용 된 세션 이외의 세션이 DML (업데이트 / 삭제 / 삽입)로 인해 잠금을 보유하고있을 때 발생합니다. 새 시스템을 개발하는 경우 사용자 나 팀의 누군가가 업데이트 문을 발행하고 큰 결과없이 세션을 종료 할 수 있습니다. 또는 누가 세션을 열 었는지 알면 해당 세션에서 커밋 할 수 있습니다.

SQL 관리 시스템에 액세스 할 수 있으면 해당 시스템을 사용하여 위반 세션을 찾으십시오. 그리고 아마 그것을 죽일.

v $ session 및 v $ lock 등을 사용할 수는 있지만 Google에서 해당 세션을 찾는 방법과 종료 방법을 제안합니다.

프로덕션 시스템에서는 실제로 다릅니다. Oracle 10g 이상에서는 다음을 실행할 수 있습니다.

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

별도의 세션에서 시간이 너무 오래 걸리는 경우를 대비하여 다음을 준비하십시오.

alter system kill session '....

그것은 당신이 가진 시스템에 달려 있으며, 오래된 시스템은 매번 커밋하지 않을 가능성이 높습니다. 오래 서있는 잠금 장치가있을 수 있으므로 문제가됩니다. 따라서 잠금 장치는 새로운 잠금 장치를 방지하고 언제 릴리스 될지 알고있는 잠금 장치를 기다립니다. 그렇기 때문에 다른 진술을 준비해야합니다. 또는 유사한 작업을 자동으로 수행하는 PLSQL 스크립트를 찾을 수 있습니다.

버전 11g에는 대기 시간을 설정하는 새로운 환경 변수가 있습니다. 나는 그것이 내가 묘사 한 것과 비슷한 것을 할 것이라고 생각합니다. 잠금 문제는 사라지지 않습니다.

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

마지막으로 시스템에 이런 종류의 유지 관리를 수행 할 사용자가 거의 없을 때까지 기다리는 것이 가장 좋습니다.


답변

내 경우에는 차단 된 세션 중 하나라고 확신했습니다 . 따라서 다음을 수행하는 것이 안전했습니다.

  • 나는 다음과 같은 위반 세션을 발견했다.

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

    세션이 비활성 상태 였지만 여전히 잠금을 유지했습니다. 귀하의 경우에 다른 WHERE 조건 을 사용해야 할 수도 있습니다 (예 : try USERNAME또는 MACHINEfield).

  • 을 사용해서 세션을 살해 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'