ORA-03114: Not Connected to Oracle - Diagnose Lost Connections
ORA-03114: Not Connected to Oracle
Section titled “ORA-03114: Not Connected to Oracle”Error Overview
Section titled “Error Overview”Error Text: ORA-03114: not connected to ORACLE
The ORA-03114 error indicates that the client process has lost its connection to the Oracle server process. Unlike ORA-03113 (end-of-file on communication channel), which signals the network-level disconnect, ORA-03114 is raised when the client attempts an Oracle call after the connection is already gone. Any work in the current transaction that had not been committed is lost. This error is common in long-running batch jobs, connection pool environments, reporting tools, and applications that hold idle connections for extended periods.
Common Causes
Section titled “Common Causes”1. Oracle Instance Shutdown or Crash
Section titled “1. Oracle Instance Shutdown or Crash”- DBA issued
SHUTDOWN IMMEDIATEorSHUTDOWN ABORTwhile sessions were active - Oracle instance crashed due to ORA-00600, ORA-07445, or OS-level OOM kill
- RAC node eviction disconnecting all sessions on that node
- Standby switchover or failover terminating primary sessions
2. Network Interruption
Section titled “2. Network Interruption”- TCP connection silently dropped by firewall, load balancer, or NAT device
- WAN link failure between application server and database server
- Network interface reset or IP address change
- VPN disconnection for remote sessions
3. Session Timeout or Resource Limit
Section titled “3. Session Timeout or Resource Limit”IDLE_TIMEprofile limit exceeded — Oracle kills idle sessionsCONNECT_TIMEprofile limit exceeded — session forcibly terminated after max durationCPU_PER_SESSIONorLOGICAL_READS_PER_SESSIONexceeded- DBA manually killed the session with
ALTER SYSTEM KILL SESSION
4. Connection Pool Stale Connections
Section titled “4. Connection Pool Stale Connections”- Connection pool returning a dead connection from its pool
- Pool validation query disabled or infrequent
- Application holding connections open across database maintenance windows
- Pool exhaustion causing connection reuse errors
5. Listener or Server Process Failure
Section titled “5. Listener or Server Process Failure”- Oracle listener process terminated while session was active
- Dedicated server process killed by OS (SIGKILL)
- Shared server dispatcher failure
- Memory corruption in server process
Diagnostic Queries
Section titled “Diagnostic Queries”Check Session and Connection Status
Section titled “Check Session and Connection Status”-- Find active sessions and time since last activitySELECT s.sid, s.serial#, s.username, s.status, s.osuser, s.machine, s.program, s.last_call_et as idle_seconds, ROUND(s.last_call_et / 60, 1) as idle_minutes, TO_CHAR(s.logon_time, 'DD-MON HH24:MI:SS') as logon_time, s.eventFROM v$session sWHERE s.username IS NOT NULLORDER BY s.last_call_et DESC;
-- Find sessions killed or marked for killSELECT sid, serial#, username, status, last_call_et, machine, programFROM v$sessionWHERE status IN ('KILLED', 'SNIPED')ORDER BY last_call_et DESC;Check Profile Limits
Section titled “Check Profile Limits”-- Review idle_time and connect_time limits for user profilesSELECT p.profile, p.resource_name, p.limitFROM dba_profiles pWHERE p.resource_name IN ( 'IDLE_TIME', 'CONNECT_TIME', 'CPU_PER_SESSION', 'LOGICAL_READS_PER_SESSION', 'SESSIONS_PER_USER' )ORDER BY p.profile, p.resource_name;
-- Check which profile each user is assignedSELECT username, profile, account_statusFROM dba_usersWHERE account_status = 'OPEN'ORDER BY profile, username;Review Recent Instance Activity
Section titled “Review Recent Instance Activity”-- Check for recent instance restartsSELECT startup_time, ROUND((SYSDATE - startup_time) * 24, 2) as hours_upFROM v$instance;
-- Check alert log for shutdown/abort eventsSELECT originating_timestamp, message_textFROM v$diag_alert_extWHERE message_text LIKE '%shutdown%' OR message_text LIKE '%abort%' OR message_text LIKE '%ORA-03114%' OR message_text LIKE '%instance terminated%'ORDER BY originating_timestamp DESCFETCH FIRST 30 ROWS ONLY;Identify Firewall-Killed Connections
Section titled “Identify Firewall-Killed Connections”-- Check for Oracle Net dead connection detection settingsSELECT name, valueFROM v$parameterWHERE name IN ( 'sqlnet.expire_time', 'tcp_keepalive', 'connection_brokers')ORDER BY name;
-- Sessions waiting on SQL*Net events (may indicate network issues)SELECT s.sid, s.serial#, s.username, s.event, s.seconds_in_wait, s.wait_class, s.stateFROM v$session sWHERE s.wait_class = 'Network' AND s.username IS NOT NULLORDER BY s.seconds_in_wait DESC;Check Connection Pool Health (Application Server Side)
Section titled “Check Connection Pool Health (Application Server Side)”-- Count connections per machine/program to detect pool behaviourSELECT machine, program, COUNT(*) as session_count, SUM(CASE WHEN status = 'ACTIVE' THEN 1 ELSE 0 END) as active_count, SUM(CASE WHEN status = 'INACTIVE' THEN 1 ELSE 0 END) as idle_count, MAX(last_call_et) as max_idle_secondsFROM v$sessionWHERE username IS NOT NULLGROUP BY machine, programORDER BY session_count DESC;Step-by-Step Resolution
Section titled “Step-by-Step Resolution”1. Verify the Instance Is Running
Section titled “1. Verify the Instance Is Running”-- From SQL*Plus or OS, confirm the instance is upSELECT instance_name, status, database_status FROM v$instance;
-- If the instance is down, start it:-- STARTUP;
-- Check that required services are registeredSELECT name, network_name, creation_date, enabledFROM dba_servicesORDER BY name;2. Verify Network Connectivity
Section titled “2. Verify Network Connectivity”Run from the application server OS:
# Test basic TCP connectivity to the listener port (usually 1521)telnet db-server-hostname 1521
# Test TNS resolutiontnsping service_name
# Check Oracle listener status on the DB serverlsnrctl statuslsnrctl services3. Configure Oracle Net Dead Connection Detection
Section titled “3. Configure Oracle Net Dead Connection Detection”Edit sqlnet.ora on the server side to enable probing of idle connections:
SQLNET.EXPIRE_TIME = 10 # Probe every 10 minutesSQLNET.RECV_TIMEOUT = 30 # Abort if no response in 30 secondsSQLNET.SEND_TIMEOUT = 30No restart is required for SQLNET.EXPIRE_TIME — it takes effect for new connections.
4. Adjust Profile Limits to Avoid Premature Disconnection
Section titled “4. Adjust Profile Limits to Avoid Premature Disconnection”-- Check if IDLE_TIME is too aggressive for your applicationSELECT profile, limit FROM dba_profilesWHERE resource_name = 'IDLE_TIME'ORDER BY profile;
-- Increase IDLE_TIME for an application profile (value in minutes)ALTER PROFILE app_profile LIMIT IDLE_TIME 60; -- 60 minutesALTER PROFILE app_profile LIMIT CONNECT_TIME UNLIMITED;
-- If no dedicated profile exists, create oneCREATE PROFILE app_profile LIMIT IDLE_TIME 60 CONNECT_TIME UNLIMITED SESSIONS_PER_USER UNLIMITED;
ALTER USER app_user PROFILE app_profile;5. Handle Stale Connections in Application Code
Section titled “5. Handle Stale Connections in Application Code”For JDBC-based applications, enable connection validation:
-- Oracle JDBC validation query (use in connection pool config)-- Set 'testOnBorrow=true' and 'validationQuery' in pool config:-- validationQuery = SELECT 1 FROM dual-- testWhileIdle = true-- timeBetweenEvictionRunsMillis = 60000-- minEvictableIdleTimeMillis = 300000For PL/SQL or SQL*Plus scripts, implement reconnect logic:
-- Test connection before using it (wrap in exception handler)DECLARE v_test NUMBER; v_connected BOOLEAN := TRUE;BEGIN BEGIN SELECT 1 INTO v_test FROM dual; EXCEPTION WHEN OTHERS THEN IF SQLCODE IN (-3114, -3113, -1012) THEN v_connected := FALSE; DBMS_OUTPUT.PUT_LINE('Connection lost — SQLCODE: ' || SQLCODE); ELSE RAISE; END IF; END;
IF v_connected THEN -- Proceed with main logic NULL; END IF;END;/6. Investigate and Stabilize Intermittent Drops
Section titled “6. Investigate and Stabilize Intermittent Drops”-- Enable SQL Trace on a suspect session to capture the disconnect pointEXEC DBMS_MONITOR.SESSION_TRACE_ENABLE(session_id => 42, serial_num => 1234, waits => TRUE);
-- After issue occurs, find the trace fileSELECT value FROM v$diag_info WHERE name = 'Diag Trace';
-- Disable tracingEXEC DBMS_MONITOR.SESSION_TRACE_DISABLE(session_id => 42, serial_num => 1234);Prevention Strategies
Section titled “Prevention Strategies”1. Implement Connection Health Monitoring
Section titled “1. Implement Connection Health Monitoring”-- Create a procedure to detect and log stale sessionsCREATE OR REPLACE PROCEDURE log_stale_sessions AS v_threshold NUMBER := 3600; -- 1 hour idle thresholdBEGIN INSERT INTO dba_session_log (sid, serial#, username, machine, idle_seconds, log_time) SELECT sid, serial#, username, machine, last_call_et, SYSDATE FROM v$session WHERE username IS NOT NULL AND status = 'INACTIVE' AND last_call_et > v_threshold; COMMIT;END;/
-- Schedule every 15 minutesBEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'LOG_STALE_SESSIONS_JOB', job_type => 'STORED_PROCEDURE', job_action => 'log_stale_sessions', repeat_interval => 'FREQ=MINUTELY;INTERVAL=15', enabled => TRUE );END;/2. Configure OS-Level TCP Keepalive
Section titled “2. Configure OS-Level TCP Keepalive”On Linux database servers, tune TCP keepalive to detect dead connections faster:
net.ipv4.tcp_keepalive_time = 300 # Start keepalive after 5 min idlenet.ipv4.tcp_keepalive_intvl = 60 # Probe every 60 secondsnet.ipv4.tcp_keepalive_probes = 5 # Drop after 5 failed probesApply without reboot: sysctl -p
3. Best Practices for Application Design
Section titled “3. Best Practices for Application Design”- Always handle
ORA-03114andORA-03113in application exception handlers and attempt reconnect - Use connection pool validation (test-on-borrow) to detect stale connections before use
- Set connection pool maximum idle time lower than Oracle’s
IDLE_TIMEprofile limit - For long-running jobs, periodically issue a lightweight heartbeat query (
SELECT 1 FROM dual) - Avoid holding connections open during long inter-step pauses in batch processes
- In RAC environments, configure TAF (Transparent Application Failover) or FAN events to handle node loss automatically
Diagnostic Scripts
Section titled “Diagnostic Scripts”These Oracle Day by Day scripts help investigate connectivity and session issues:
- gvsess.sql — Active session analysis across RAC nodes
- health.sql — Database health check including session and process counts
Related Errors
Section titled “Related Errors”- ORA-03113 - End-of-file on communication channel
- ORA-01012 - Not logged on
- ORA-00028 - Your session has been killed
- ORA-12541 - TNS no listener
- ORA-12560 - TNS protocol adapter error
Emergency Response
Section titled “Emergency Response”Quick Fixes
Section titled “Quick Fixes”-
Verify the instance is accessible
SELECT instance_name, status FROM v$instance; -
Check if the session was killed
SELECT sid, serial#, username, status FROM v$sessionWHERE status IN ('KILLED', 'SNIPED'); -
Re-establish the connection — simply reconnect from your client tool or application. Any uncommitted work from the lost session is automatically rolled back by Oracle’s PMON process.
-
Check if profile killed the session due to idle time
SELECT profile, resource_name, limit FROM dba_profilesWHERE resource_name = 'IDLE_TIME' AND limit != 'UNLIMITED';
Post-Resolution Cleanup
Section titled “Post-Resolution Cleanup”-- Clean up any KILLED sessions still visible in v$session (PMON handles this automatically)SELECT sid, serial#, username, status, last_call_etFROM v$sessionWHERE status = 'KILLED';
-- Verify no orphaned locks remain from the dropped sessionSELECT lo.session_id, lo.oracle_username, lo.os_user_name, lo.locked_mode, do.object_name, do.object_typeFROM v$locked_object loJOIN dba_objects do ON lo.object_id = do.object_idORDER BY lo.session_id;
-- If locks remain from a dead session, kill the session explicitlyALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;