2026년 10월 23일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-00057 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-00057 maximum number of temporary table locks exceeded 는?
ORA-00057 에러는 Oracle 데이터베이스에서 임시 테이블(Temporary Table)에 대한 잠금(Lock) 수가 시스템에서 허용하는 최대치를 초과했을 때 발생합니다. Oracle은 내부적으로 임시 테이블 세그먼트를 관리하기 위해 잠금 리소스를 사용하는데, 동시에 너무 많은 세션이 임시 테이블에 접근하거나, 단일 세션 내에서 지나치게 많은 임시 테이블 잠금을 요청할 경우 이 에러가 트리거됩니다. 주로 대규모 병렬 처리 환경이나 글로벌 임시 테이블(GTT, Global Temporary Table)을 과도하게 활용하는 OLTP 시스템에서 자주 목격되는 에러입니다.
주요 발생 원인
1. 과도한 동시 세션에서의 글로벌 임시 테이블(GTT) 접근
글로벌 임시 테이블은 세션마다 독립적인 데이터를 유지하지만, 내부적으로는 공유 딕셔너리 객체를 사용하기 때문에 잠금 리소스를 소모합니다. 수백 개 이상의 세션이 동시에 동일한 GTT에 접근할 경우, Oracle 내부 잠금 한도에 도달하여 ORA-00057이 발생할 수 있습니다.
2. 트랜잭션 종료 없이 반복적인 임시 테이블 생성/삭제
애플리케이션 로직에서 임시 테이블을 트랜잭션 내에서 반복적으로 생성하고 커밋 없이 롤백하거나 방치하면 잠금이 해제되지 않고 누적됩니다. 특히 PL/SQL 루프 내부에서 동적 DDL(Dynamic DDL)로 임시 테이블을 반복 생성하는 패턴이 이 문제를 야기하는 대표적인 사례입니다.
3. 잘못된 임시 테이블스페이스 구성 및 TEMP 세그먼트 부족
임시 테이블스페이스의 용량이 부족하거나 TEMP 세그먼트 익스텐트 수가 한계에 달하면, Oracle이 새로운 잠금 슬롯을 확보하지 못해 에러가 발생합니다. 임시 테이블스페이스 그룹(Temporary Tablespace Group)이 제대로 구성되지 않았을 경우에도 특정 인스턴스에 부하가 몰려 이 에러를 유발할 수 있습니다.
해결 방법
원인 1: 동시 세션 수 과다 — 현황 진단 및 세션 정리
먼저 현재 임시 테이블 잠금 현황과 세션 정보를 확인합니다.
-- 현재 활성 세션 중 임시 세그먼트를 사용 중인 세션 조회
SELECT s.sid,
s.serial#,
s.username,
s.status,
s.osuser,
s.machine,
t.blocks AS temp_blocks_used,
t.tablespace
FROM v$session s
JOIN v$tempseg_usage t ON s.saddr = t.session_addr
ORDER BY t.blocks DESC;
-- 임시 테이블 잠금 현황 확인
SELECT sid,
type,
id1,
id2,
lmode,
request,
ctime,
block
FROM v$lock
WHERE type = 'TT' -- TT: Temporary Table lock
ORDER BY ctime DESC;
불필요한 세션이 발견되면 해당 세션을 종료합니다.
-- 특정 세션 종료 (sid와 serial# 입력)
ALTER SYSTEM KILL SESSION '123,4567' IMMEDIATE;
-- 특정 사용자의 모든 유휴 세션 종료 스크립트 생성
SELECT 'ALTER SYSTEM KILL SESSION ''' || sid || ',' || serial# || ''' IMMEDIATE;'
FROM v$session
WHERE username = 'APP_USER'
AND status = 'INACTIVE'
AND last_call_et > 3600; -- 1시간 이상 비활성 세션
원인 2: 반복적 DDL 처리 — 애플리케이션 코드 수정 및 GTT 전환
동적으로 임시 테이블을 생성/삭제하는 패턴을 글로벌 임시 테이블(GTT)로 대체합니다.
-- 기존 문제가 되는 패턴 (루프 내 임시 테이블 반복 생성 - 금지)
-- BEGIN
-- FOR i IN 1..100 LOOP
-- EXECUTE IMMEDIATE 'CREATE TABLE temp_work_' || i || ' AS SELECT ...';
-- END LOOP;
-- END;
-- 권장 패턴: GTT를 사전에 생성하고 재사용
-- ON COMMIT DELETE ROWS: 커밋 시 데이터 자동 삭제 (트랜잭션 범위)
CREATE GLOBAL TEMPORARY TABLE gtt_work_data (
id NUMBER,
value VARCHAR2(200),
process_dt DATE,
status VARCHAR2(10)
)
ON COMMIT DELETE ROWS;
-- GTT 활용 예시
BEGIN
-- 데이터 삽입
INSERT INTO gtt_work_data (id, value, process_dt, status)
SELECT employee_id,
last_name,
SYSDATE,
'PENDING'
FROM employees
WHERE department_id = 10;
-- 중간 처리 로직 수행
UPDATE gtt_work_data
SET status = 'PROCESSED'
WHERE id > 100;
-- 결과 활용
SELECT COUNT(*) FROM gtt_work_data WHERE status = 'PROCESSED';
COMMIT; -- 커밋 시 GTT 데이터 자동 삭제 (ON COMMIT DELETE ROWS)
END;
/
-- ON COMMIT PRESERVE ROWS: 세션 종료 시 데이터 삭제 (세션 범위)
CREATE GLOBAL TEMPORARY TABLE gtt_session_data (
id NUMBER,
value VARCHAR2(500)
)
ON COMMIT PRESERVE ROWS;
원인 3: 임시 테이블스페이스 확장 및 재구성
임시 테이블스페이스 현황을 점검하고 필요시 확장합니다.
-- 임시 테이블스페이스 사용 현황 조회
SELECT tablespace_name,
ROUND(tablespace_size * 8192 / 1024 / 1024, 2) AS total_mb,
ROUND(allocated_space * 8192 / 1024 / 1024, 2) AS allocated_mb,
ROUND(free_space * 8192 / 1024 / 1024, 2) AS free_mb,
ROUND((1 - free_space/NULLIF(tablespace_size,0)) * 100, 2) AS used_pct
FROM v$temp_space_header
ORDER BY used_pct DESC;
-- TEMP 테이블스페이스 데이터파일 추가
ALTER TABLESPACE temp
ADD TEMPFILE '/u01/oradata/ORCL/temp02.dbf'
SIZE 4G
AUTOEXTEND ON NEXT 512M MAXSIZE 20G;
-- 임시 테이블스페이스 그룹 생성 (RAC 환경 권장)
ALTER TABLESPACE temp TABLESPACE GROUP temp_group;
ALTER TABLESPACE temp2 TABLESPACE GROUP temp_group;
-- 사용자별 임시 테이블스페이스 재지정
ALTER USER app_user TEMPORARY TABLESPACE temp_group;
-- 현재 사용 중인 TEMP 세그먼트 강제 축소 (Oracle 11g 이상)
ALTER TABLESPACE temp SHRINK SPACE KEEP 1G;
예방 방법
1. 글로벌 임시 테이블(GTT) 설계 원칙 정립과 커넥션 풀 최적화
애플리케이션 설계 단계부터 반복적인 DDL 작업 대신 GTT를 표준으로 채택하고, 동일한 GTT를 여러 목적으로 재사용하도록 설계합니다. 또한 커넥션 풀(Connection Pool) 크기를 실제 필요한 수준으로 조정하여 불필요한 동시 세션이 임시 잠금 리소스를 점유하지 않도록 관리합니다. 모니터링 스크립트를 주기적으로 실행하여 임시 잠금 수가 임계치에 근접하는 시점을 사전에 포착하는 것이 중요합니다.
-- 임시 잠금 현황 주기적 모니터링 쿼리 (crontab 등으로 자동화 권장)
SELECT COUNT(*) AS tt_lock_count,
MAX(ctime) AS max_lock_duration_sec
FROM v$lock
WHERE type = 'TT';
2. 임시 테이블스페이스 자동 확장 설정 및 정기 점검 루틴 수립
임시 테이블스페이스 데이터파일에 AUTOEXTEND를 활성화하고 MAXSIZE를 서버 디스크 용량의 60~70% 이내로 설정하여 갑작스러운 부하 증가에 대비합니다. 매주 또는 매월 단위로 임시 테이블스페이스 사용률, 세션별 TEMP 사용량, 장기 미커밋 트랜잭션을 점검하는 DBA 루틴을 수립하고, 이를 Oracle Enterprise Manager(OEM) 또는 커스텀 알림 스크립트와 연동하면 운영 안정성을 크게 높일 수 있습니다.
-- 장기 미커밋 트랜잭션 탐지 (30분 이상)
SELECT s.sid,
s.serial#,
s.username,
s.machine,
t.start_time,
ROUND((SYSDATE - TO_DATE(t.start_time,'MM/DD/YY HH24:MI:SS')) * 1440, 1) AS duration_min
FROM v$session s
JOIN v$transaction t ON s.taddr = t.addr
WHERE (SYSDATE - TO_DATE(t.start_time,'MM/DD/YY HH24:MI:SS')) * 1440 > 30
ORDER BY duration_min DESC;
관련 에러
- ORA-01652:
unable to extend temp segment by N in tablespace— 임시 테이블스페이스 공간 부족 에러로, ORA-00057과 함께 발생하는 경우가 많습니다. TEMP 파일 추가 또는 AUTOEXTEND 설정으로 해결합니다. - ORA-00054:
resource busy and acquire with NOWAIT specified— 잠금 경합이 심화될 때 함께 나타나며, 세션 간 Lock 충돌 상황을 나타냅니다. - ORA-04031:
unable to allocate N bytes of shared memory— Shared Pool 부족 에러로, 과도한 동적 DDL 사용 시 하드파싱(Hard Parsing)이 증가하여 동반 발생할 수 있습니다. - ORA-01555:
snapshot too old— 장기 트랜잭션과 맞물려 임시 세그먼트와 Undo 리소스 부족이 복합적으로 발생할 때 연관됩니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.