본문 바로가기
Database/Oracle

[ORACLE] ORA-01000 : 최대 커서 수 초과 오류 해결 및 예방 가이드

by Papa Martino V 2025. 7. 27.
728x90

ORA-01000 : 최대 커서 수 초과 오류 해결 및 예방 가이드
[ORACLE] ORA-01000

 

Oracle 데이터베이스를 활용한 서비스 운영 중, 갑작스러운 성능 저하나 트랜잭션 실패가 발생했을 때 ORA-01000: maximum open cursors exceeded 오류는 종종 그 원인으로 등장합니다. 단순한 SQL 실행 문제로 보일 수 있지만, 이 오류는 DB 자원 관리 실패와 깊은 관련이 있으며, 장기적인 서비스 운영 안정성에 큰 영향을 미칠 수 있습니다.

본 글에서는 ORA-01000 오류의 개념부터 원인, 실무에서 자주 겪는 시나리오, 그리고 궁극적인 해결과 예방 전략까지 실제 엔지니어링 경험을 바탕으로 상세히 정리하였습니다.

1. ORA-01000 오류란?

ORA-01000 오류는 한 세션에서 동시에 열 수 있는 커서(cursor)의 개수를 초과했을 때 발생하는 오류입니다. 오라클은 성능 최적화를 위해 SQL 문장을 파싱하여 커서로 관리하며, 각 세션마다 커서의 최대 개수를 제한합니다. 이 제한을 초과할 경우 더 이상 SQL을 실행할 수 없습니다.

에러 메시지: ORA-01000: maximum open cursors exceeded

기본적으로 오라클은 커서를 자동으로 닫지만, 개발자가 명시적으로 close하지 않거나, 커서가 누적되는 구조의 애플리케이션이라면 이 오류는 언제든지 발생할 수 있습니다.

2. 주요 원인 분석

원인 유형 설명 대표 사례
커서 누수(Cursor Leak) 명시적으로 커서를 닫지 않아 누적 JDBC, PL/SQL에서 커서 close 누락
SQL 재사용 실패 같은 논리지만 매번 다른 SQL 구조로 파싱됨 동적 SQL에 값 직접 삽입
커서 수 설정 부족 초기 DB 설정의 open_cursors 값이 너무 작음 대량 병렬 처리 시도 시 오류 발생
프레임워크 내부 처리 문제 ORM 또는 커넥션 풀에서 리소스 미정리 Spring, Hibernate 등에서 close 누락

3. 오류 발생 예제

3-1. PL/SQL 커서 누수 예시


DECLARE
  c SYS_REFCURSOR;
BEGIN
  FOR i IN 1..1000 LOOP
    OPEN c FOR 'SELECT * FROM employees WHERE employee_id = ' || i;
    -- CLOSE c; -- 누락!
  END LOOP;
END;

해결: 커서를 매 루프마다 닫아야 합니다.


...
    CLOSE c;
...

3-2. Java JDBC 사용 시 커서 누수 예시


Connection conn = ...;
for (int i = 0; i < 1000; i++) {
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM table WHERE id = " + i);
    // stmt.close(); rs.close(); 누락!
}

해결: try-with-resources 또는 finally 블록으로 stmt.close()rs.close()를 반드시 호출해야 합니다.

4. 시스템 설정 점검 및 조정

4-1. 현재 세션의 커서 수 확인


SELECT s.username, s.sid, s.serial#, COUNT(*) AS open_cursors
FROM v$open_cursor c
JOIN v$session s ON c.sid = s.sid
GROUP BY s.username, s.sid, s.serial#;

4-2. 시스템 최대 커서 수 확인


SHOW PARAMETER open_cursors;

4-3. 설정 변경

기본값은 보통 300이며, 트래픽이 많은 시스템에서는 더 높게 설정합니다.


ALTER SYSTEM SET open_cursors = 1000 SCOPE=BOTH;

주의: 설정 변경은 DBA 권한이 필요하며, 시스템 자원과 커넥션 수에 따라 신중히 설정해야 합니다.

5. 실무 적용 가이드라인

  • SQL 실행 후 ResultSet, Statement, PreparedStatement는 반드시 close()
  • Connection Pool 사용 시, 프레임워크가 close를 보장하는지 확인
  • 동일한 쿼리는 PreparedStatement로 재사용하도록 설계
  • 커서 사용이 많은 서비스는 오류 모니터링 시스템에 커서 개수 로그를 추가
  • PL/SQL 루프 내 OPEN-CLOSE 명확히 정의

6. 해결 방법 요약 비교

상황 원인 해결 방법
PL/SQL 반복문 커서 커서 닫기 누락 반복마다 OPEN 후 CLOSE
JDBC 사용 시 Statement/ResultSet 누락 try-with-resources로 자원 자동 반납
ORM 사용 시 커넥션 풀 리소스 자동 반납 실패 설정 확인 및 명시적 close()
대규모 서비스 open_cursors 기본값 초과 DB 설정값 조정 (DBA 협의)

7. 디버깅 및 예방법 체크리스트

  1. SQL 또는 로직 내 커서 OPEN 후 CLOSE가 있는가?
  2. 동적 SQL 또는 반복 로직 내 중복 커서 생성이 있는가?
  3. DB 설정값(open_cursors)이 충분한가?
  4. 애플리케이션에서 커넥션 풀 설정은 적절히 되어 있는가?
  5. 모니터링을 통해 커서 사용량 추적이 가능한가?

8. 결론

ORA-01000 오류는 단순히 커서 수가 부족해서가 아니라, 코드와 아키텍처 수준에서 자원 해제에 대한 책임이 명확하지 않을 때 발생하는 현상입니다. 이를 예방하기 위해서는 개발 초기 단계에서부터 커서와 자원 사용에 대한 철저한 정책 수립과, 자동화된 리소스 관리 체계 도입이 중요합니다.

문제 발생 후 대응이 아닌, 예방적 관점에서 커서 사용을 설계하는 습관은 장기적인 시스템 안정성 확보의 핵심입니다.

출처

  • Oracle Database Reference Guide - 공식 문서
  • Oracle Dev Forum: ORA-01000 토론 사례 - Oracle Community
  • Effective Java, 3rd Edition - Joshua Bloch (자원 관리와 자동 해제 참고)
728x90