2026년 09월 08일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-12170 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-12170 TNS: Connect timeout occurred 는?
ORA-12170 에러는 Oracle Net(TNS)이 원격 데이터베이스에 연결을 시도하는 과정에서 지정된 시간 내에 응답을 받지 못할 때 발생하는 네트워크 연결 타임아웃 에러입니다. 클라이언트가 서버에 연결 요청을 보낸 후 리스너(Listener) 또는 서버 프로세스로부터 제때 응답을 받지 못하면 TNS 레이어에서 이 에러를 반환합니다. 실무에서는 네트워크 장애, 방화벽 설정 오류, 리스너 과부하, 또는 잘못된 TNS 구성 등 다양한 원인으로 인해 빈번하게 발생하며, 애플리케이션 운영 중단으로 이어질 수 있는 심각한 에러입니다.
주요 발생 원인
1. 방화벽 또는 네트워크 장비에 의한 패킷 차단
가장 흔하고 파악이 어려운 원인 중 하나입니다. 클라이언트와 데이터베이스 서버 사이의 방화벽, 로드밸런서, 또는 네트워크 장비가 Oracle TNS 포트(기본 1521)로 향하는 패킷을 차단하거나 세션을 중간에 끊어버리는 경우 발생합니다. 특히 방화벽의 유휴 세션 타임아웃(Idle Session Timeout) 정책이 Oracle의 연결 유지 시간보다 짧게 설정되어 있을 때 자주 발생하며, 이 경우 연결 자체는 시도되지만 결코 완성되지 않아 클라이언트 측에서 타임아웃 에러로 나타납니다.
2. Oracle Listener 과부하 또는 비정상 상태
Oracle Listener는 클라이언트의 연결 요청을 받아 서버 프로세스로 전달하는 핵심 컴포넌트입니다. Listener가 과도한 연결 요청으로 인해 큐가 꽉 찬 상태이거나, 비정상적으로 종료된 상태이거나, 또는 네트워크 인터페이스 바인딩이 잘못된 경우 클라이언트의 연결 요청이 타임아웃될 수 있습니다. 특히 대규모 배치 작업 직후나 애플리케이션 서버가 일제히 재시작되는 상황(Connection Storm)에서 Listener가 순간적으로 처리 한계를 초과하면 이 에러가 집중적으로 발생합니다.
3. sqlnet.ora 및 tnsnames.ora 잘못된 타임아웃 설정
sqlnet.ora 파일의 SQLNET.INBOUND_CONNECT_TIMEOUT 또는 CONNECT_TIMEOUT 파라미터가 너무 짧게 설정되어 있을 경우, 네트워크 지연이 조금이라도 발생하면 연결이 완료되기도 전에 타임아웃이 발생합니다. 또한 tnsnames.ora에서 CONNECT_TIMEOUT 값이 네트워크 환경에 맞지 않게 설정되어 있거나, 존재하지 않는 호스트명 또는 잘못된 포트 번호가 기재된 경우에도 동일한 에러가 발생합니다. 이 설정값들은 환경에 맞게 튜닝되어야 하며, 너무 짧거나 너무 긴 값 모두 운영 문제를 일으킬 수 있습니다.
해결 방법
1. 네트워크 및 방화벽 연결 확인
먼저 기본적인 네트워크 연결과 포트 접근 가능 여부를 확인합니다.
-- 클라이언트 서버에서 OS 명령으로 포트 연결 테스트 (SQL*Plus 외부)
-- Linux/Unix:
-- telnet <DB_HOST> 1521
-- nc -zv <DB_HOST> 1521
-- tnsping을 이용한 리스너 응답 확인
-- tnsping <TNS_ALIAS> 10
-- 리스너 상태 확인 (DB 서버에서)
-- lsnrctl status
-- lsnrctl services
-- 데이터베이스 서버에서 현재 연결 대기 세션 확인
SELECT s.sid,
s.serial#,
s.status,
s.username,
s.machine,
s.program,
s.wait_class,
s.event,
s.seconds_in_wait
FROM v$session s
WHERE s.status = 'INACTIVE'
AND s.username IS NOT NULL
ORDER BY s.seconds_in_wait DESC;
2. sqlnet.ora 타임아웃 파라미터 조정
서버 측 sqlnet.ora 파일($ORACLE_HOME/network/admin/sqlnet.ora)에서 타임아웃 관련 파라미터를 적절히 조정합니다.
-- 현재 sqlnet.ora 파라미터를 DB에서 확인하는 쿼리
SELECT name, value
FROM v$parameter
WHERE name IN (
'sqlnet.inbound_connect_timeout',
'sqlnet.recv_timeout',
'sqlnet.send_timeout'
);
-- sqlnet.ora 파일에 설정할 권장 파라미터 예시 (파일 직접 편집)
-- SQLNET.INBOUND_CONNECT_TIMEOUT = 60 (기본값 60초, 너무 짧으면 늘림)
-- SQLNET.RECV_TIMEOUT = 30
-- SQLNET.SEND_TIMEOUT = 30
-- SQLNET.EXPIRE_TIME = 10 (방화벽 세션 차단 방지용 Keep-Alive)
3. tnsnames.ora CONNECT_TIMEOUT 설정 수정
클라이언트 측 tnsnames.ora 파일에서 타임아웃 및 Retry 설정을 조정합니다.
-- tnsnames.ora 예시 설정 (권장)
-- ORCL =
-- (DESCRIPTION =
-- (CONNECT_TIMEOUT=30)(RETRY_COUNT=3)(RETRY_DELAY=3)
-- (ADDRESS = (PROTOCOL = TCP)(HOST = mydbserver.example.com)(PORT = 1521))
-- (CONNECT_DATA =
-- (SERVER = DEDICATED)
-- (SERVICE_NAME = orcl.example.com)
-- )
-- )
-- 현재 리스너에 등록된 서비스 확인 (DB 서버)
SELECT name,
network_name,
pdb,
creation_date
FROM v$services
ORDER BY name;
4. 방화벽 유휴 세션 차단 대응 (SQLNET.EXPIRE_TIME 설정)
방화벽이 장시간 유휴 상태인 TCP 세션을 강제로 끊는 문제를 해결하려면 Oracle 측에서 Dead Connection Detection(DCD) 또는 Keep-Alive를 활성화합니다.
-- 현재 오래된 유휴 세션 목록 확인
SELECT s.sid,
s.serial#,
s.username,
s.status,
s.machine,
ROUND((SYSDATE - s.logon_time) * 24, 2) AS hours_connected,
s.last_call_et AS idle_seconds
FROM v$session s
WHERE s.type = 'USER'
AND s.status = 'INACTIVE'
AND s.last_call_et > 300 -- 5분 이상 유휴
ORDER BY s.last_call_et DESC;
-- sqlnet.ora에 아래 파라미터 추가 후 리스너 재시작
-- SQLNET.EXPIRE_TIME = 10 (단위: 분, 10분마다 Keep-Alive 패킷 전송)
5. 리스너 재시작 및 상태 점검
-- 리스너 로그에서 타임아웃 관련 에러 확인 (OS 명령)
-- tail -100f $ORACLE_BASE/diag/tnslsnr/<hostname>/listener/trace/listener.log
-- grep "TNS-12170\|TNS-12535\|TNS-12606" listener.log
-- 리스너 재시작 (OS 명령)
-- lsnrctl stop
-- lsnrctl start
-- DB Alert 로그에서 관련 에러 확인
SELECT originating_timestamp,
message_text
FROM v$diag_alert_ext
WHERE message_text LIKE '%ORA-12170%'
OR message_text LIKE '%TNS-12170%'
ORDER BY originating_timestamp DESC
FETCH FIRST 50 ROWS ONLY;
예방 방법
1. SQLNET.EXPIRE_TIME 및 적절한 타임아웃 파라미터 표준화
모든 Oracle 환경의 sqlnet.ora에 SQLNET.EXPIRE_TIME=10을 설정하여 방화벽에 의한 TCP 세션 강제 종료를 예방합니다. 또한 SQLNET.INBOUND_CONNECT_TIMEOUT은 네트워크 RTT(왕복 지연 시간)를 고려하여 최소 60초 이상으로 설정하고, tnsnames.ora에는 RETRY_COUNT=3, RETRY_DELAY=3을 추가하여 일시적인 네트워크 순단에도 자동으로 재시도할 수 있도록 구성합니다. 이 설정은 운영 표준 문서에 포함시켜 신규 서버 구성 시 항상 적용되도록 체계화하는 것이 중요합니다.
2. 정기적인 리스너 모니터링 및 연결 수 관리
Listener의 연결 큐 상태와 현재 활성 연결 수를 주기적으로 모니터링하여 임계치 초과 시 사전에 대응할 수 있는 체계를 구축합니다. Oracle Enterprise Manager, Zabbix, 또는 커스텀 스크립트를 활용하여 lsnrctl status 출력의 연결 대기 수가 일정 임계값을 초과하면 즉시 알람이 발생하도록 설정합니다. 또한 Connection Pool(UCP, DBCP 등)을 사용하는 애플리케이션의 경우 Pool 설정을 최적화하여 불필요한 연결 요청이 리스너에 집중되지 않도록 관리하는 것이 중요합니다.
관련 에러
- ORA-12535 (TNS: operation timed out): ORA-12170과 유사하지만, 이미 연결이 수립된 이후 데이터 송수신 중 타임아웃이 발생할 때 나타납니다.
- ORA-12541 (TNS: no listener): 리스너 자체가 실행되지 않거나 해당 포트에서 응답하지 않을 때 발생합니다.
- ORA-12543 (TNS: destination host unreachable): 네트워크 라우팅 문제로 목적지 호스트에 아예 도달하지 못할 때 발생합니다.
- ORA-12606 (TNS: application timeout occurred): 애플리케이션 레벨에서 설정된 타임아웃이 초과될 때 발생하며, sqlnet.ora의
SQLNET.OUTBOUND_CONNECT_TIMEOUT설정과 관련됩니다. - TNS-12535: ORA-12170 에러와 함께 리스너 로그에 자주 동반 출력되는 에러로, 동일한 네트워크 타임아웃 상황을 리스너 관점에서 기록한 것입니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.