Skip to content

Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out #126

@sungam3r

Description

@sungam3r

Hi. We were faced with the fact that we began to constantly receive exceptions in various of our services associated with a timeout when establishing a connection:

Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out
   at OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch)
   at OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, OracleConnection connRefForCriteria, String affinityInstanceName, Boolean bForceMatch)
   at OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, OracleConnection connRefForCriteria)
   at Oracle.ManagedDataAccess.Client.OracleConnection.Open()
   at System.Data.Common.DbConnection.OpenAsync(CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)

Oracle.EntityFrameworkCore 3.19.80
Oracle.ManagedDataAccess.Core 2.19.80/100

Errors occur both on test environments and in production. At first I suspected that our services were exhausting all available connections in the connection pool (we use pooling as it is enabled by default). I thought about this after reading the documentation. So I wanted to test the hypothesis using performance counters (see #123) but counters work only on Windows and our backend runs in Kubernetes. So I started looking for other ways. I knew about the possibilities to enable tracing. At the same time, I did not want to load our services with tracing. In addition, the trace is not very convenient to write to a file. So I wanted to manually access the inner classes and read the state of the connection pool. Fortunately, I noticed the OracleConnection.Dump() method, which is also used by the tracing itself. I examined the source code for this method and realized that it outputs the status of the pool - the total number of connections in the pool and the number of free connections. This information was perfect for me for analysis. I started calling this method in EF Core interceptor every time a connection level error occurred (Microsoft.EntityFrameworkCore.Diagnostics.ConnectionErrorEventData). The results surprised me. It turns out that the error in most cases occurs when the pool is empty. Output from OracleConnection.Dump():

(DUMP)

What can you advise in such a situation? Also I saw this article.
I want to note that we get errors even during the initial warm up of the services, when we make a call to our databases in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions