Oracle DBMS 를 운영하다보면 자주 만나는 에러가 ORA-01000 입니다.
ORA-01000: maximum open cursors exceeded
ORA-01000: 최대 열기 커서 수를 초과했습니다
open cursor 의 갯수가 설정된 Max 값을 초과했다는 의미입니다.
설정된 open cursor 최대값은 sys 유저에서 show parameter open_cursors 커맨드로 조회해 볼 수 있습니다.
1000 으로 설정되어 있는데, 한 세션에서 1000개 이상 커서를 오픈하게 되면 ORA-01000 에러를 만납니다.
아래와 같이 테스트해서 상황을 재현해 볼 수 있습니다.
-- 테스트 프로시져 생성
CREATE OR REPLACE PROCEDURE proc_test1
AS
ii number;
v_cur integer;
BEGIN
for ii in 1 .. 2000 loop
dbms_output.put(' ii => ' || ii);
v_cur := dbms_sql.open_cursor;
dbms_sql.parse(v_cur, 'select 1 from dual where 1 = ' || ii, dbms_sql.native);
--dbms_sql.close_cursor(v_cur);
end loop;
dbms_output.put_line('----------------------');
END;
/
-- 테스트 프로시져 실행
set serveroutput on
exec proc_test1;
|
위 프로시져는 2000번 루핑을 돌면서 커서를 Open 했다가 Close 하는 프로시져 입니다.
일부러, close_cursor() 호출하는 부분을 주석처리(--)해서 실행이 안되도록 했습니다.
이렇게 하면, 커서가 너무 많이 오픈되면서 에러가 발생하게 됩니다.
어떤 세션에서 커서를 많이 오픈한 건지 아래와 같은 SQL문으로 조회해 볼 수 있습니다.
select a.sid, s.process, s.machine, s.module, s.action, count(*) as cnt
from V$OPEN_CURSOR a, V$SESSION s
where s.sid = a.sid
group by a.sid, s.process, s.machine, s.module, s.action
having count(*) > 100
order by count(*) desc;
|
DB 파라메타 open_cursors = 1000 을 넘는 것을 확인할 수 있습니다.
위에 나온 SID 를 이용해서 어떤 SQL 인지도 확인해 볼 수 있습니다.
주의할 것은 위 V$OPEN_CURSOR 뷰에 있는 정보는 ORA-01000 에러를 유발한 세션이 살아있는 동안만 남아있습니다.
ORA-01000 에러를 발생시킨 프로그램이 세션을 종료해버리면, 정보도 함께 사라집니다.
그리고, 한번 ORA-01000 에러가 발생한 세션은 해당 세션에서 다른 SQL이 실행되어도 계속 ORA-01000 에러가 발생합니다.
해당 세션은 아직 살아있고 Open 된 커서는 여전히 Close 되지 못한 상황이기 때문입니다.
위에서처럼 Dynamic SQL 을 사용하고, 프로그램에서 반복문(for/while)을 사용해서 커서가 오픈되는 경우에 주로 발생합니다.
가급적 Dynamic SQL 은 변수를 사용하는 Static SQL 로 바꿔주는 것이 좋습니다.
불가피한 경우, 반복문 횟수를 줄이거나, open_cursors 파라메타값을 늘려주면 에러가 덜 발생합니다.
SQL> alter system set open_cursors = 2000 scope=both;
'IT관련' 카테고리의 다른 글
오라클 Index 모니터링 - 안쓰는 인덱스 찾기 (index monitoring), Foreign Key 주의 (0) | 2021.02.06 |
---|---|
오라클 에러 정보 (JBO-25014) - Another user has changed the row with primary key oracle.jbo.Key (0) | 2021.02.04 |
Oracle 샘플 테스트 데이터 생성 프로그램 다운로드 (Data Maker) (5) | 2021.01.19 |
테이블 자동 시리얼 번호 컬럼 Auto Increment Identity Column (오라클 12c 신기능) (0) | 2020.12.30 |
오라클 정규표현식 함수 regexp_replace 샘플예제 (날짜 포맷 변경하기 SQL문) (0) | 2020.12.10 |