2026년 09월 08일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-12163 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-12163 TNS: connect descriptor is too long 는?
ORA-12163 에러는 Oracle Net Services(TNS)에서 접속 디스크립터(Connect Descriptor)의 길이가 허용된 최대값을 초과했을 때 발생하는 에러입니다. Oracle은 TNS 접속 문자열의 길이에 제한을 두고 있으며, 이 한계를 넘어서면 클라이언트가 데이터베이스 서버에 연결을 시도할 때 해당 에러가 발생합니다. 일반적으로 복잡한 FAILOVER 구성, 다수의 ADDRESS 항목, 또는 잘못 구성된 tnsnames.ora 파일에서 주로 발생합니다.
주요 발생 원인
1. tnsnames.ora 파일 내 접속 디스크립터가 지나치게 길게 설정된 경우
tnsnames.ora 파일에서 하나의 TNS 별칭(Alias)에 너무 많은 ADDRESS 항목이나 불필요하게 긴 파라미터가 포함될 경우 ORA-12163이 발생합니다. Oracle TNS는 내부적으로 접속 디스크립터의 최대 길이 제한(일반적으로 255바이트 또는 설정에 따라 최대 4000자 수준)을 두고 있으며, 이를 초과하면 파싱 단계에서 에러가 발생합니다. 특히 RAC(Real Application Clusters) 환경에서 여러 노드의 주소를 모두 나열하거나, FAILOVER 및 LOAD_BALANCE 옵션을 중첩하여 사용할 때 이 문제가 빈번하게 발생합니다.
2. Easy Connect(EZCONNECT) 또는 LDAP 방식에서 잘못된 긴 접속 문자열 사용
Oracle Easy Connect 방식이나 LDAP 기반 접속에서 비표준적인 방식으로 매우 긴 접속 문자열을 직접 코드나 스크립트에 하드코딩한 경우에도 이 에러가 발생할 수 있습니다. 예를 들어 JDBC 드라이버를 사용하는 애플리케이션에서 직접 DESCRIPTION 블록 전체를 URL로 넘기는 경우, 문자열 길이가 Oracle 내부 제한을 초과할 수 있습니다. 이 경우 접속 문자열 자체를 TNS 별칭으로 단순화하거나 tnsnames.ora를 올바르게 활용해야 합니다.
3. sqlnet.ora 또는 네트워크 설정 파일의 잘못된 구성
sqlnet.ora 파일에서 NAMES.DEFAULT_DOMAIN, NAMES.DIRECTORY_PATH 등의 설정이 잘못되거나 충돌할 경우, TNS가 내부적으로 여러 해석 경로를 거치면서 최종 디스크립터의 길이가 늘어나 에러가 발생하기도 합니다. 특히 도메인 이름 자동 추가 기능이 활성화된 상태에서 이미 도메인이 포함된 별칭을 사용할 경우, 중복 도메인 추가로 인해 접속 문자열이 예상보다 훨씬 길어질 수 있습니다. sqlnet.ora와 tnsnames.ora의 설정이 서로 일관성을 유지하고 있는지 반드시 확인해야 합니다.
해결 방법
원인 1 해결: tnsnames.ora 접속 디스크립터 단순화
복잡하게 구성된 tnsnames.ora 항목을 아래와 같이 정리하고 최소화합니다.
잘못된 예시 (너무 긴 디스크립터):
-- tnsnames.ora 내 잘못된 설정 예시 (개념적 표현)
-- 실제로는 텍스트 파일이지만, 구조 파악을 위해 표기
/*
MYDB_LONG =
(DESCRIPTION =
(FAILOVER = ON)
(LOAD_BALANCE = ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = server1.mycompany.internal.domain.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = server2.mycompany.internal.domain.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = server3.mycompany.internal.domain.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = server4.mycompany.internal.domain.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = server5.mycompany.internal.domain.com)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = mydb.mycompany.internal.domain.com)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 10)
(DELAY = 5)
)
)
)
*/
올바른 예시 (단순화된 디스크립터):
-- tnsnames.ora 개선된 설정 예시
/*
MYDB =
(DESCRIPTION =
(FAILOVER = ON)
(LOAD_BALANCE = ON)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = server1)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = server2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = mydb)
)
)
*/
접속 디스크립터의 현재 길이를 SQL*Plus에서 간접적으로 확인하는 방법:
-- 현재 접속된 DB 서비스명 및 인스턴스 확인
SELECT SYS_CONTEXT('USERENV', 'SERVICE_NAME') AS service_name,
SYS_CONTEXT('USERENV', 'INSTANCE_NAME') AS instance_name,
SYS_CONTEXT('USERENV', 'SERVER_HOST') AS server_host
FROM DUAL;
-- TNS 관련 설정 파일 경로 확인 (DBA_DIRECTORIES 또는 V$ 뷰 활용)
SELECT NAME, VALUE
FROM V$PARAMETER
WHERE NAME IN ('service_names', 'db_domain', 'local_listener', 'remote_listener');
원인 2 해결: Easy Connect 문자열 최적화
코드나 스크립트에 하드코딩된 긴 접속 문자열을 TNS 별칭으로 교체합니다.
-- Java/JDBC 환경에서 잘못된 긴 접속 문자열 사용 예 (개념 표현)
-- 아래처럼 전체 DESCRIPTION을 코드에 직접 삽입하면 ORA-12163 발생 가능
/*
String url = "jdbc:oracle:thin:@(DESCRIPTION=(FAILOVER=ON)(LOAD_BALANCE=ON)" +
"(ADDRESS=(PROTOCOL=TCP)(HOST=very-long-server-hostname.internal.domain.com)(PORT=1521))" +
"(ADDRESS=(PROTOCOL=TCP)(HOST=another-long-server-hostname.internal.domain.com)(PORT=1521))" +
"(CONNECT_DATA=(SERVICE_NAME=very_long_service_name.internal.domain.com)))";
*/
-- 개선: tnsnames.ora에 별칭 등록 후 짧은 별칭 사용
/*
String url = "jdbc:oracle:thin:@MYDB"; -- tnsnames.ora의 별칭 사용
*/
-- Oracle에서 현재 등록된 서비스 목록 확인
SELECT NAME, NETWORK_NAME, CREATION_DATE
FROM DBA_SERVICES
ORDER BY NAME;
-- 리스너에 등록된 서비스 상태 확인 (동적 뷰)
SELECT INST_ID, NAME, NETWORK_NAME
FROM GV$SERVICES
ORDER BY NAME;
원인 3 해결: sqlnet.ora 설정 검토 및 수정
-- Oracle 파라미터에서 DB_DOMAIN 설정 확인
SELECT NAME, VALUE, DESCRIPTION
FROM V$PARAMETER
WHERE NAME = 'db_domain';
-- sqlnet.ora의 도메인 설정 관련 파라미터 확인
-- (실제 sqlnet.ora 파일을 직접 편집해야 하며, 아래는 설정 예시)
/*
-- sqlnet.ora 수정 예시:
# 도메인 자동 추가 비활성화 (이미 FQDN을 사용하는 경우)
NAMES.DEFAULT_DOMAIN = (없음 또는 실제 도메인만 기재)
# 해석 순서를 단순화
NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)
*/
-- 접속 테스트 전 TNS_ADMIN 경로 확인
SELECT VALUE
FROM V$PARAMETER
WHERE NAME = 'tns_admin';
-- 또는 OS 환경변수 확인을 위한 외부 프로시저 활용 (가능한 경우)
SELECT SYS_CONTEXT('USERENV', 'DB_NAME') AS db_name,
SYS_CONTEXT('USERENV', 'DB_DOMAIN') AS db_domain
FROM DUAL;
예방 방법
1. tnsnames.ora 파일의 정기적인 감사 및 표준화
운영 환경에서 tnsnames.ora 파일은 시간이 지남에 따라 불필요한 항목이나 지나치게 복잡한 디스크립터로 가득 차는 경향이 있습니다. 분기 1회 이상 정기적으로 tnsnames.ora를 리뷰하여 사용하지 않는 별칭을 제거하고, 호스트명은 가급적 짧은 별칭이나 IP 주소를 사용하도록 표준화하십시오. tnsping 유틸리티를 CI/CD 파이프라인에 통합하여 변경 사항이 배포되기 전에 자동으로 접속 테스트를 수행하도록 구성하는 것을 강력히 권장합니다.
-- OS 명령어로 tnsping을 활용한 사전 검증 (DBA 스크립트 예시)
-- $ tnsping MYDB
-- $ tnsping MYDB 10
-- DB 접속 후 네트워크 관련 이벤트 로깅 활성화 여부 확인
SELECT NAME, VALUE
FROM V$PARAMETER
WHERE NAME LIKE '%audit%' OR NAME LIKE '%log%'
ORDER BY NAME;
2. Oracle Connection Manager(CMAN) 또는 Oracle Cloud 접속 활용
복잡한 RAC 환경이나 다수의 노드가 있는 환경에서는 개별 클라이언트의 tnsnames.ora를 복잡하게 만드는 대신, Oracle Connection Manager(CMAN)를 중간 계층으로 도입하여 접속 디스크립터를 단순화하십시오. 클라이언트는 CMAN의 단일 주소만 알면 되므로, 접속 디스크립터의 길이가 극적으로 줄어들며 ORA-12163과 같은 에러를 근본적으로 예방할 수 있습니다. Oracle 19c 이상에서는 Easy Connect Plus 문법도 활용할 수 있습니다.
관련 에러
- ORA-12154: TNS:could not resolve the connect identifier specified — tnsnames.ora에서 별칭 자체를 찾지 못할 때 발생하며, ORA-12163과 함께 TNS 설정 문제를 진단할 때 쌍으로 확인해야 합니다.
- ORA-12170: TNS:Connect timeout occurred — 접속 디스크립터가 올바르더라도 네트워크 타임아웃이 발생하는 경우로, 방화벽 또는 리스너 문제와 연관됩니다.
- ORA-12514: TNS:listener does not currently know of service requested — 리스너에 서비스가 등록되지 않은 경우 발생하며, tnsnames.ora의 SERVICE_NAME 설정과 실제 DB 서비스명 불일치 시 나타납니다.
- ORA-12533: TNS:illegal ADDRESS parameters — 잘못된 ADDRESS 파라미터 형식이 사용될 때 발생하며, 역시 tnsnames.ora 설정 오류와 밀접하게 연관됩니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.