포스트

ORA-12514 리스너 서비스 오류의 원인과 해결

리스너까지 연결됐지만 서비스 이름이 등록되어 있지 않아 나는 ORA-12514 오류를, PMON 동적 등록 메커니즘부터 lsnrctl 진단까지 정리한다.

ORA-12514 리스너 서비스 오류의 원인과 해결

ORA-12514는 리스너까지 연결은 됐지만, 접속 문자열의 서비스 이름과 일치하는 서비스가 리스너에 등록되어 있지 않을 때 나는 오류다. 네트워크/방화벽 문제가 아니라 “리스너가 그 서비스를 모른다”는 뜻이다.

증상

1
ORA-12514, TNS:listener does not currently know of service requested in connect descriptor

연결이 리스너까지 도달해서 리스너에게 거부당한 상태다. 즉 호스트/포트로 리스너에는 정상 접근했다는 의미이므로 네트워크 계층은 배제할 수 있다. 문제는 그다음 단계 — 리스너가 요청받은 서비스로 세션을 넘겨줄 수 없다는 것이다.

원인

TNS 연결이 이뤄지는 흐름

Oracle 접속은 세 주체가 있다.

  • 리스너(listener): 지정 포트(보통 1521)에서 접속 요청을 받는 프로세스. 요청의 서비스 이름을 보고 해당 인스턴스로 세션을 넘긴다.
  • 인스턴스(instance): 실제 DB 프로세스. 자신이 제공하는 서비스 이름(service name)을 리스너에 등록한다.
  • 클라이언트: JDBC URL의 서비스 이름/SID로 “이 서비스에 붙여달라”고 요청한다.

핵심은 인스턴스가 서비스를 리스너에 동적으로 등록(dynamic registration)한다는 점이다. 등록은 인스턴스의 백그라운드 프로세스 PMON이 담당한다.1

서비스 이름과 SID는 URL 문법 자체가 다르다.

1
2
jdbc:oracle:thin:@//host:1521/service_name   ← 서비스 이름 (슬래시)
jdbc:oracle:thin:@host:1521:sid               ← SID (콜론)

왜 이 오류가 나는가 (원인 3가지)

  1. JDBC URL의 서비스 이름이 틀림. 가장 흔한 실수는 서비스 이름 자리에 SID를 쓰거나 그 반대. 위 문법 차이(슬래시 vs 콜론)를 혼동하면 리스너가 아는 이름과 매칭이 안 된다. 서비스 이름은 설정에 따라 대소문자도 구분된다.

  2. 인스턴스가 내려가 있거나 아직 등록 전. 리스너가 떠 있어도 PMON이 서비스를 등록하기 전이면 리스너는 모른다. DB가 막 재시작됐다면 등록 완료까지 지연이 있다.

  3. 리스너가 재시작됨. 리스너를 새로 띄우면 등록 정보가 초기화되어, 인스턴스가 다시 등록할 때까지 서비스를 모른다. 재등록은 자동으로 약 60초 정도 걸리거나 ALTER SYSTEM REGISTER로 즉시 강제할 수 있다.

멀티테넌트(PDB) 환경이면 닫힌 PDB도 원인이다. PDB가 닫혀 있으면 해당 서비스가 리스너에 등록되지 않는다.

해결

진단 — DB 서버에서

리스너에 실제로 등록된 서비스 목록을 본다.

1
2
lsnrctl status
lsnrctl services

출력의 Service 항목이 리스너가 아는 서비스 이름이다. JDBC URL에서 슬래시 뒤의 값이 이 목록과 정확히 일치해야 한다. 인스턴스 쪽에서도 무엇을 등록하려 하는지 확인할 수 있다.

1
2
SELECT value FROM v$parameter WHERE name = 'service_names';
SELECT value FROM v$parameter WHERE name = 'db_unique_name';

lsnrctl이 “command not found”라면 보통 둘 중 하나다.

  • 실행 위치가 잘못됨. 애플리케이션(Spring Boot) 서버가 아니라 Oracle DB 서버에서 실행해야 한다. 앱 서버엔 Oracle이 없을 가능성이 크다.
  • PATH에 Oracle 환경변수 미로드. DB 서버에 들어가도 oracle 계정 환경이 안 잡히면 못 찾는다.
1
2
3
su - oracle
echo $ORACLE_HOME
$ORACLE_HOME/bin/lsnrctl status

ORACLE_HOME이 비어 있으면 oratab에서 확인한다.

1
cat /etc/oratab

조치

  • 문제 데이터소스의 JDBC URL 서비스 이름을 lsnrctl services 출력과 대조한다. 정상 동작하는 다른 데이터소스 URL과 비교하면 차이가 바로 보인다.
  • SID인데 슬래시 문법으로 썼다면 콜론 문법으로 바꾼다 (반대도 마찬가지).
  • DB가 방금 시작됐다면 재시도하거나, DB에서 즉시 재등록을 강제한다.
1
ALTER SYSTEM REGISTER;
  • 멀티테넌트면 대상 PDB가 열려 있는지 확인한다.
1
ALTER PLUGGABLE DATABASE ... OPEN;

DB 서버 접근 권한이 없을 때

  • tnsping (Oracle 클라이언트가 있으면): tnsping <서비스이름>
  • JDBC URL 직접 점검: application.yml 등에서 문제 데이터소스 URL을 찾아 슬래시/콜론과 서비스 이름을 확인. ORA-12514는 거의 항상 슬래시 뒤 서비스 이름이 틀렸을 때 난다.
  • DBA에게 문의: “리스너에 등록된 서비스 이름 목록”을 요청하는 게 가장 빠르다.

정리

ORA-12514는 네트워크 오류가 아니라 “리스너가 요청받은 서비스를 모른다”는 등록 문제다. 리스너는 인스턴스의 PMON이 서비스를 동적으로 등록해줘야 비로소 그 서비스를 안다. 따라서 원인은 세 갈래로 좁혀진다 — JDBC URL의 서비스 이름/SID 혼동, 인스턴스 미기동·등록 지연, 리스너 재시작 후 재등록 대기(멀티테넌트라면 닫힌 PDB). 진단은 lsnrctl status로 리스너가 아는 서비스 목록을 확인하는 것에서 시작하고, 필요하면 ALTER SYSTEM REGISTER로 즉시 재등록을 강제한다.

  1. 12c부터는 동적 등록을 전담하는 LREG(Listener Registration) 프로세스가 분리되어, 19c+에서는 PMON이 아니라 LREG가 이 등록을 수행한다. 등록 메커니즘·타이밍(기본 60초 주기, ALTER SYSTEM REGISTER로 즉시 강제)은 동일하므로 진단 흐름은 그대로다. 리스너는 자신이 켜졌다고 서비스를 아는 게 아니라, 인스턴스가 등록해줘야 비로소 안다. 그래서 리스너와 인스턴스의 기동 순서·타이밍이 어긋나면 “리스너는 살아있는데 서비스는 모르는” 상태가 생긴다. ↩︎

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.