Oracle ORA 에러 트러블슈팅 모음
상위: Database MOC
개요
Oracle 접속·조회에서 만나는 에러는 코드만 봐서는 원인이 헷갈리지만, “어느 계층에서 났는가”로 나누면 대처가 명확해진다. 이 문서는 자주 부딪히는 ORA/DPY 에러를 (1) 네트워크·리스너, (2) 객체·권한, (3) 대용량·동시성, (4) 드라이버 네 계층으로 분류하고 각 에러의 원인과 대처를 표로 정리한다. 진단 순서의 원칙은 항상 아래에서 위로다. 네트워크로 서버에 닿는가 → 리스너가 서비스를 아는가 → 인증되는가 → 객체가 보이는가 → 쿼리가 자원 한계에 걸리는가.
원리
접속이 성립하는 4단계
[클라이언트] --TCP--> [리스너] --핸드오프--> [DB 인스턴스] --인증--> [세션] --권한--> [객체]
| | | | |
ORA-12170 ORA-12514/12505 ORA-03113/03114 로그인 실패 ORA-00942
(경로/방화벽) (서비스/SID 불일치) (연결 끊김) (객체/시노님)에러 번호를 이 사슬 위에 올려 놓으면, 어디를 먼저 확인할지가 정해진다. 예컨대 ORA-12170은 TCP 경로 문제이므로 방화벽/포트부터 보고, ORA-00942는 이미 인증까지 된 뒤 객체 해석 단계이므로 오너·시노님·권한을 본다.
SERVICE_NAME vs SID
리스너 관련 오류의 절반은 접속 문자열에서 서비스 식별자를 잘못 지정해 생긴다. Oracle은 두 방식을 구분한다.
| 방식 | connect string 키 | 의미 |
|---|---|---|
| 서비스 이름 | SERVICE_NAME | 리스너에 등록된 논리 서비스 |
| 인스턴스 SID | SID | 물리 인스턴스 식별자 |
리스너가 아는 것과 클라이언트가 요청하는 것이 어긋나면 ORA-12514(서비스 모름) 또는 ORA-12505(SID 모름)가 난다. lsnrctl status로 리스너가 실제 광고하는 이름을 확인하는 것이 핵심이다.
실전
진단 커맨드
# 1) 네트워크로 리스너 포트에 닿는가
nc -vz db-host 1521
# 2) 리스너가 어떤 서비스를 광고하는가 (SERVICE_NAME/SID 확인)
lsnrctl status
tnsping my_service
# 3) 접속 테스트 (easy connect: host:port/service_name)
sqlplus user/pw@db-host:1521/my_service# python-oracledb: thin(기본) vs thick
import oracledb
# thin 모드 (Instant Client 불필요)
conn = oracledb.connect(user="u", password="pw", dsn="db-host:1521/my_service")
# 구버전 서버/구형 verifier로 thin이 막히면 thick 모드
oracledb.init_oracle_client() # Instant Client 필요
conn = oracledb.connect(user="u", password="pw", dsn="db-host:1521/my_service")객체·권한 확인
-- ORA-00942: 실제 객체 오너/시노님 확인
SELECT owner, object_type FROM all_objects WHERE object_name = 'RECORDS';
SELECT table_owner, table_name FROM all_synonyms WHERE synonym_name = 'RECORDS';
-- 현재 세션 사용자/스키마
SELECT sys_context('USERENV','CURRENT_USER'),
sys_context('USERENV','CURRENT_SCHEMA') FROM dual;함정·트러블슈팅
네트워크·리스너
| 에러 | 의미 | 원인 | 대처 |
|---|---|---|---|
ORA-12170 | 접속 타임아웃 | 방화벽/경로/포트 차단, 서버 도달 불가 | nc/tnsping으로 경로 확인, 방화벽·보안그룹 점검 |
ORA-12514 | 리스너가 서비스 모름 | SERVICE_NAME 오타/미등록 | lsnrctl status로 광고 서비스 확인 후 문자열 정정 |
ORA-12505 | 리스너가 SID 모름 | SID↔SERVICE_NAME 혼동 | easy connect는 service_name 사용, 정확한 식별자로 교체 |
ORA-03113 | 통신 채널 끝에 EOF | 세션 강제 종료, 서버 크래시, 유휴 타임아웃 | alert log 확인, 네트워크 장비 idle timeout 점검 |
ORA-03114 | DB에 미접속 | 이미 끊긴 세션에 재사용 시도 | 재연결/풀 재획득 |
객체·권한
| 에러 | 의미 | 원인 | 대처 |
|---|---|---|---|
ORA-00942 | 테이블/뷰 없음 | 이름이 시노님이고 실제 객체는 다른 오너, 또는 권한 부재 | 오너 수식(owner.object) 조회, all_synonyms/권한 확인 |
ORA-01031 | 권한 부족 | GRANT 누락 | 필요한 SELECT/EXECUTE 권한 부여 |
v$ 접근 거부 | 카탈로그 뷰 권한 | 세션 계정에 SELECT_CATALOG_ROLE 없음 | ”없음”으로 단정 말고 DBA에 권한 요청 |
대용량·동시성
| 에러 | 의미 | 원인 | 대처 |
|---|---|---|---|
ORA-01555 | snapshot too old | 오래 도는 벌크 SELECT 중 UNDO 재사용 | 청킹/keyset 페이징, UNDO_RETENTION 상향, 커밋 간격 조정 |
ORA-00060 | deadlock detected | 교차 순서 락 획득 | 재시도(백오프), 트랜잭션 내 락 획득 순서 통일 |
ORA-01652 | temp 세그먼트 확장 실패 | 대량 정렬/해시가 TEMP 초과 | TEMP 테이블스페이스 확장, 정렬 줄이기 |
드라이버 (python-oracledb)
| 에러 | 의미 | 원인 | 대처 |
|---|---|---|---|
DPY-3010 | thin 모드 미지원 서버 | 구버전 DB가 thin 프로토콜 미지원 | thick 모드 + Instant Client 사용 |
DPY-3015 | 구형 password verifier | 예전 방식 비밀번호 해시 | thick 모드로 전환, 또는 비밀번호 재설정으로 verifier 갱신 |
ORA-01555는 근본적으로 “너무 오래 읽어서” 생긴다. 대량 추출은 한 커서로 몇 시간 읽지 말고 keyset(마지막 키 이후) 방식으로 청킹한다. 상세는 03.데이터 추출 (청킹·keyset·ORA-01555) 참조.DPY-3010/3015는 thin↔thick 전환으로 대부분 해결된다. thick은 OS에 Instant Client와 (Linux면) libaio가 필요하다. 상세는 02.접속 확립 (thin·thick·libaio·NLS) 참조.v$뷰가 안 보인다고 기능이 없는 게 아니다 — 카탈로그 권한 문제일 수 있으니 DBA에게 권한을 확인한다.
정리
- 에러는 “네트워크 → 리스너 → 인증 → 객체 → 자원” 사슬 위에 올려 아래에서 위로 진단한다.
- 리스너 오류(
ORA-12514/12505)의 흔한 원인은SERVICE_NAME↔SID혼동이다.lsnrctl status로 실제 광고 이름을 확인한다. ORA-00942는 인증 이후 객체 해석 문제다. 시노님·오너·권한을 본다.ORA-01555는 청킹/keyset으로,ORA-00060은 락 순서 통일과 재시도로, 드라이버DPY-3010/3015는 thick 모드로 대응한다.
관련: 02.접속 확립 (thin·thick·libaio·NLS) · 03.데이터 추출 (청킹·keyset·ORA-01555) · 01.마이그레이션 개요와 전략