Skip to content

Why do my Oracle database connections fail with ORA-17800 even though the processes parameter hasn't been reached?

13 minute read
Content level: Advanced
0

Oracle PX server processes spawned by parallel queries exhaust the processes limit (ORA-00020), even though application connections are well below 4000. The resmgr:pq queued wait event shows sessions queued for parallel resources. Resolve by lowering PARALLEL_MAX_SERVERS, reducing PARALLEL_SERVERS_TARGET, adjusting Resource Manager plan directives, or reducing parallel query DOP.

Issue

I'm using Amazon RDS for Oracle. My application receives "ORA-17800: Got minus one from a read call" errors when trying to connect to my database. The processes parameter is set to 4000, and the alert log shows ORA-00020: maximum number of processes (4000) exceeded. However, the number of application database connections is well below 4000. In Performance Insights, I see the resmgr:pq queued wait event on Top SQL.

Description

Oracle Database uses parallel execution to accelerate data-intensive operations such as large table scans, hash joins, and aggregation queries. When a SQL statement is eligible for parallel execution, Oracle spawns multiple parallel execution (PX) server processes that work concurrently on portions of the data. The query coordinator process orchestrates the PX servers and assembles the final result. The degree of parallelism (DOP) determines how many PX server processes a single statement uses. For example, a statement running at DOP 16 requires 16 PX server processes (or 32 if the execution plan includes both a producer and consumer set of PX servers). Each PX server process counts as a separate OS process — they all consume from the same processes parameter pool.

Each PX server process counts as a separate operating system process on the database instance. This means parallel statements consume processes from the same pool governed by the processes initialization parameter. A single user session running a DOP 16 query can consume 16–32 additional process slots beyond its own session process. When multiple users run parallel queries concurrently, the total PX server demand can grow rapidly.

To prevent parallel queries from monopolizing all available resources and starving serial workloads, Oracle introduced parallel statement queuing controlled by the PARALLEL_SERVERS_TARGET initialization parameter. This parameter defines the threshold at which new parallel statements are queued rather than immediately executed. It is deliberately set lower than PARALLEL_MAX_SERVERS (the hard ceiling for parallel server processes) to create a buffer zone. When the total number of active PX servers across all sessions reaches PARALLEL_SERVERS_TARGET, any new parallel statement that would exceed this threshold is placed into a wait queue. The session remains connected but enters the resmgr:pq queued wait event until enough PX servers become available.

Oracle Database Resource Manager provides fine-grained control over this queuing mechanism through consumer groups and resource plan directives. A resource plan assigns database sessions to consumer groups based on criteria such as the user, application module, or service name. Each consumer group can have its own parallel_server_limit — a percentage cap of the PARALLEL_SERVERS_TARGET pool that the group is allowed to consume. This means a consumer group can hit its individual parallel server limit and start queuing its statements even when the system-wide PARALLEL_SERVERS_TARGET has not yet been reached. The Resource Manager also controls dequeue priority via the shares directive, which determines the probability that a consumer group's queued statements are dequeued next when resources free up.

In this scenario, the combination of high parallel query demand and Resource Manager throttling causes a cascade of events that ultimately results in ORA-17800 connection failures:

  1. Parallel server processes exhaust the processes limit: Multiple concurrent parallel queries spawn PX server processes that, combined with regular user sessions and background processes, push the total OS process count to the processes parameter ceiling (4000). The alert log records: ORA-00020: maximum number of processes (4000) exceeded.
  2. Session queue buildup with resmgr:pq queued: Sessions waiting on the Resource Manager parallel queue still occupy process/session slots. Each queued session has already authenticated and established a session — it holds a process but is waiting rather than executing.
  3. New connections rejected: Once processes is exhausted, Oracle cannot fork new server processes for incoming connections. The listener cannot hand off the connection to a dedicated server process.
  4. ORA-17800 at the JDBC layer: The JDBC driver receives an unexpected end-of-stream (minus one from a read call) because the server-side cannot complete the connection handshake. This manifests as ORA-17800.

The key insight is that the processes limit (4000) is being reached, but not by application user connections alone. PX server processes spawned by parallel queries consume the majority of the process pool. From the application's perspective, the number of DB connections is well below 4000, yet the database cannot accept new connections because internal PX processes have consumed the remaining slots.

Important: Increasing the processes parameter requires an RDS instance reboot. Both PARALLEL_MAX_SERVERS and PARALLEL_SERVERS_TARGET are dynamic parameters (no reboot required in 19c and 21c). However, simply increasing PARALLEL_SERVERS_TARGET does not help if the root problem is that PX processes are already exhausting processes — it would allow even more PX servers to run concurrently, potentially making the problem worse.

The correct resolution is to limit the number of parallel server processes so they cannot exhaust the processes pool. This is achieved by lowering PARALLEL_MAX_SERVERS, reducing PARALLEL_SERVERS_TARGET, adjusting the Resource Manager parallel_server_limit per consumer group, or reducing the DOP of the offending queries.

This article explains how to diagnose the issue by checking parallel server utilization, reviewing the active Resource Manager plan and its consumer group directives, and resolving the problem by tuning PARALLEL_SERVERS_TARGET, adjusting plan directives, or reducing parallel query demand.

Resolution

Immediate recovery when the database cannot accept new connections

If the database is currently unreachable and you cannot establish a new session to run diagnostic queries, use the following steps to restore connectivity:

Step 1: Reboot the RDS instance (if immediate recovery is needed)

Reboot the RDS instance or stop some application servers to release DB processes. A reboot terminates all sessions (including queued PX sessions) and restarts the instance with a clean process pool. Use this only when immediate recovery is critical and other options are not feasible.

Step 2: Lower parallel_max_servers to cap PX server spawning

If you can establish at least one connection, immediately lower parallel_max_servers to prevent further PX server process spawning.

On RDS Oracle, modify parallel_max_servers via the parameter group:

  1. Open the Amazon RDS console.
  2. Choose Parameter groups, and then choose your custom parameter group.
  3. Set parallel_max_servers to 0.
  4. Choose Apply immediately.

Setting it to 0 prevents any new parallel server processes from being spawned. This is a dynamic parameter — it takes effect immediately without a reboot. Existing PX server processes continue running until they complete, but no new ones are created.

Once the situation stabilizes and process slots free up, you can set it to an appropriate value (e.g., 200–500) rather than leaving it at 0.

Step 3: Disable the Resource Manager plan (to release queued sessions)

If you can establish at least one connection (for example, through a retry from the application or a brief window when a queued session completes), disable the Resource Manager plan to stop parallel statement queuing.

Set resource_manager_plan to empty via the parameter group:

  1. Open the Amazon RDS console.
  2. Choose Parameter groups, and then choose your custom parameter group.
  3. Set resource_manager_plan to an empty string (blank).
  4. Choose Apply immediately.

This is a dynamic parameter — it takes effect immediately without a reboot (see Set up Database Resource Manager in Amazon RDS for Oracle). When the Resource Manager is disabled, sessions currently waiting on resmgr:pq queued are released from the queue because the queuing mechanism itself is removed.

Important: Only perform this step after Step 2 (lowering parallel_max_servers). Since disabling the Resource Manager releases all queued sessions at once, they will attempt to spawn PX servers simultaneously. With parallel_max_servers already lowered in Step 2, the released sessions are bounded and cannot worsen the ORA-00020 condition.

Step 4: Kill queued sessions to free connection slots

If you can connect, terminate sessions stuck on resmgr:pq queued to immediately free connection capacity. On RDS Oracle, use rdsadmin.rdsadmin_util.disconnect (see Killing a session).

First, identify the queued sessions:

SELECT sid, serial#, username, seconds_in_wait
FROM V$SESSION
WHERE EVENT = 'resmgr:pq queued'
AND SECONDS_IN_WAIT > 300;

Then disconnect each session using the sid and serial# from the query above:

BEGIN
  rdsadmin.rdsadmin_util.disconnect(sid => <sid>, serial => <serial#>);
END;
/

Repeat for each queued session. This frees process/session slots so new connections can succeed.

After connectivity is restored, proceed with the diagnostic steps below to identify and fix the root cause.

Identify the root cause

The resmgr:pq queued wait event means that parallel query statements are being queued by Oracle Resource Manager. This happens when:

  • The number of active parallel execution (PX) server processes reaches PARALLEL_SERVERS_TARGET.
  • Each parallel query spawns multiple PX server processes that count toward the total process usage on the instance.
  • Sessions waiting in the queue hold connection slots but aren't actively processing, which reduces available capacity for new connections.
  • When connection slots are exhausted or the connection handshake times out, the JDBC driver receives ORA-17800 ("Got minus one from a read call").

Note: The processes parameter defines the maximum total OS processes for the instance. However, Resource Manager imposes a lower effective concurrency limit for parallel workloads through PARALLEL_SERVERS_TARGET. This parameter is intentionally set lower than PARALLEL_MAX_SERVERS to ensure each parallel statement gets all the parallel server resources it requires and to prevent overloading the system.

Understand how Oracle Resource Manager controls parallel statement queuing

Oracle Database Resource Manager uses consumer groups and resource plan directives to control parallel statement execution. The following directives affect parallel queuing behavior:

DirectiveDescription
parallel_server_limitMaximum percentage of the PARALLEL_SERVERS_TARGET pool that a consumer group can use. When this limit is reached, additional parallel statements from that group are queued.
parallel_queue_timeoutMaximum time (in seconds) a statement can remain queued. After timeout, the statement is terminated with ORA-7454 or allowed to run (depending on PQ_TIMEOUT_ACTION).
parallel_degree_limit_p1Maximum degree of parallelism (DOP) for any operation in that consumer group.
sharesControls the dequeue priority across consumer groups. Higher shares = higher probability of being dequeued first.

How it works:

  1. When PARALLEL_DEGREE_POLICY is set to AUTO, Oracle queues parallel statements if running them would increase active parallel servers above PARALLEL_SERVERS_TARGET.
  2. Each consumer group has its own parallel statement queue. When parallel_server_limit for a consumer group is reached, statements from that group are queued even if the system-wide PARALLEL_SERVERS_TARGET hasn't been reached.
  3. When parallel servers become available, the shares directive determines which consumer group's queued statement is dequeued next.
  4. Serial (non-parallel) statements execute immediately regardless of parallel statement queuing.

Check current parallel server usage

Run the following query to compare active parallel servers against the target threshold:

SELECT
  (SELECT VALUE FROM V$PARAMETER WHERE NAME = 'parallel_servers_target') AS pq_target,
  (SELECT VALUE FROM V$PARAMETER WHERE NAME = 'parallel_max_servers') AS pq_max,
  (SELECT COUNT(*) FROM V$PX_SESSION) AS active_px_sessions;

Check sessions waiting on resmgr:pq queued

Run the following query to identify queued sessions:

SELECT sid, serial#, username, status, event, seconds_in_wait
FROM V$SESSION
WHERE EVENT = 'resmgr:pq queued'
ORDER BY seconds_in_wait DESC;

Check the active Resource Manager plan and directives

Identify the active plan and review how parallel resources are allocated per consumer group:

-- Active Resource Manager plan
SELECT VALUE FROM V$PARAMETER WHERE NAME = 'resource_manager_plan';

-- Plan directives with parallel controls
SELECT plan,
       group_or_subplan,
       shares,
       parallel_server_limit,
       parallel_degree_limit_p1,
       parallel_queue_timeout
FROM DBA_RSRC_PLAN_DIRECTIVES
WHERE plan = (SELECT REPLACE(VALUE, 'FORCE:', '')
              FROM V$PARAMETER
              WHERE NAME = 'resource_manager_plan');

Check which consumer group each session belongs to:

SELECT s.sid, s.serial#, s.username, s.event,
       rm.consumer_group_name, rm.state
FROM V$SESSION s
JOIN V$RSRC_SESSION_INFO rm ON s.sid = rm.sid
WHERE s.event = 'resmgr:pq queued';

Option 1: Lower PARALLEL_MAX_SERVERS and PARALLEL_SERVERS_TARGET

Since PX server processes are exhausting the processes limit, the primary fix is to cap the number of parallel servers so they cannot consume all available process slots. Lower PARALLEL_MAX_SERVERS to reserve process capacity for user connections and background processes.

Recommended formula:

PARALLEL_MAX_SERVERS ≤ processes - (expected_user_sessions + background_processes + safety_margin)

For example, if you expect 2000 user sessions, ~100 background processes, and want a 200-process safety margin:

PARALLEL_MAX_SERVERS = 4000 - 2000 - 100 - 200 = 1700

  1. Open the Amazon RDS console.
  2. Choose Parameter groups, and then choose your custom parameter group.
  3. Lower parallel_max_servers (e.g., to 1700) and parallel_servers_target (e.g., to 1200 — lower than parallel_max_servers to enable queuing as a buffer).
  4. AApply the changes. Note: Both parallel_max_servers and parallel_servers_target are dynamic parameters (no reboot needed in Oracle 19c and 21c).

Important: Do NOT increase PARALLEL_SERVERS_TARGET in this scenario — that would allow more PX servers to run concurrently and worsen the process exhaustion problem.

Option 2: Adjust the Resource Manager plan directives

If a specific consumer group's parallel_server_limit is too restrictive, increase it to allow that group more parallel server capacity:

BEGIN
  DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();

  DBMS_RESOURCE_MANAGER.UPDATE_PLAN_DIRECTIVE(
    plan                        => 'YOUR_PLAN_NAME',
    group_or_subplan            => 'YOUR_CONSUMER_GROUP',
    new_parallel_server_limit   => 80,   -- Increase from current value (e.g., 50 to 80%)
    new_parallel_degree_limit_p1 => 8    -- Optionally adjust DOP limit
  );

  DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();
END;
/

Key considerations:

  • parallel_server_limit is a percentage of the total PARALLEL_SERVERS_TARGET. For example, if PARALLEL_SERVERS_TARGET = 64 and parallel_server_limit = 50, the consumer group can use at most 32 parallel servers before its statements are queued.
  • If a low-priority consumer group has a small parallel_server_limit, but a high-priority group has a high limit, the high-priority group can exhaust the pool, causing low-priority sessions to queue indefinitely.
  • You can also set parallel_queue_timeout to prevent statements from waiting too long in the queue. When the timeout expires, the statement is either terminated (ORA-7454) or allowed to run based on the PQ_TIMEOUT_ACTION directive.

Option 3: Reduce the degree of parallelism (DOP)

If queries are using an excessively high DOP, reduce it at the session or statement level:

ALTER SESSION SET PARALLEL_DEGREE_LIMIT = 4;

Or disable parallel query for specific sessions:

ALTER SESSION DISABLE PARALLEL QUERY;

Option 4: Identify and tune high-parallelism queries

Find the queries that consume the most parallel server resources:

SELECT sql_id, sql_text, px_servers_executions
FROM V$SQL
WHERE px_servers_executions > 0
ORDER BY px_servers_executions DESC
FETCH FIRST 20 ROWS ONLY;

Add the /*+ NO_PARALLEL */ hint to queries that don't require parallel execution, or reduce the parallel degree attribute on the tables:

ALTER TABLE schema_name.table_name PARALLEL 2;

You can also use the /*+ NO_STATEMENT_QUEUING */ hint to let specific critical statements bypass the parallel statement queue:

SELECT /*+ NO_STATEMENT_QUEUING */ column_list
FROM large_table
WHERE conditions;

Note: Statements that bypass the queue can cause the system to exceed PARALLEL_SERVERS_TARGET. Only use this hint for critical operations.

Related information

AWS
EXPERT

published 2 months ago188 views