Forum Stats

  • 3,741,231 Users
  • 2,248,397 Discussions
  • 7,861,693 Comments

Discussions

ArgumentNullException (paramname "key") when archivelog mode ran out of space

LeChuck
LeChuck Member Posts: 10 Red Ribbon
edited Sep 21, 2018 7:52AM in ODP.NET

Hi,

I noticed a strange behavior: we got an ArgumentNullException when trying to connect to an Oracle server:

System.ArgumentNullException: value cannot be null.

Parametername: key

bei System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)

  bei System.Collections.Generic.Dictionary`2.FindEntry(TKey key)

  bei OracleInternal.Common.SyncDictionary`2.ContainsKey(K k)

  bei OracleInternal.ConnectionPool.PoolManager`3.CreateServiceCtx(PR pr)

  bei OracleInternal.ConnectionPool.PoolManager`3.PutNewPR(PR pr, Boolean bForPoolPopulation)

  bei OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount, Boolean bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, CriteriaCtx criteriaCtx, String instanceName, List`1 switchFailedInstNames)

  bei OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, CriteriaCtx criteriaCtx, String affinityInstanceName, Boolean bForceMatch)

  bei OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, CriteriaCtx criteriaCtx, String affinityInstanceName, Boolean bForceMatch)

  bei OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword, CriteriaCtx criteriaCtx)

  bei Oracle.ManagedDataAccess.Client.OracleConnection.Open()

I'm using Managed ODP.Net 4.122.1.20170524. After some digging via dotPeek the problematic code seems to be in OracleInternal.ConnectionPool.PoolManager<>.CreateServiceCtx():

<span class="keyword keyword-private token">private</span> <span class="keyword token keyword-void">void</span> <span class="token function">CreateServiceCtx</span><span class="punctuation token">(</span>PR pr<span class="punctuation token">)</span><br/><span class="punctuation token">{</span><br/>  <span class="keyword keyword-string token">string</span> serviceName <span class="operator token">=</span> pr<span class="punctuation token">.</span>ServiceName<span class="punctuation token">;</span><br/>  <span class="keyword keyword-if token">if</span> <span class="punctuation token">(</span><span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_dictSvcCtx<span class="punctuation token">.</span><span class="token function">ContainsKey</span><span class="punctuation token">(</span>serviceName<span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="comment token">// <-- this fails with an ArgumentNullException because serviceName is null; pr is the OracleConnectionImpl instance</span><br/>   <span class="keyword keyword-return token">return</span><span class="punctuation token">;</span><br/>  <span class="keyword keyword-lock token">lock</span> <span class="punctuation token">(</span><span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_dictSvcCtx<span class="punctuation token">)</span><br/>  <span class="punctuation token">{</span><br/>   <span class="keyword keyword-if token">if</span> <span class="punctuation token">(</span><span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_dictSvcCtx<span class="punctuation token">.</span><span class="token function">ContainsKey</span><span class="punctuation token">(</span>serviceName<span class="punctuation token">)</span><span class="punctuation token">)</span><br/>   <span class="keyword keyword-return token">return</span><span class="punctuation token">;</span><br/>   <span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_dictSvcCtx<span class="punctuation token">[</span>serviceName<span class="punctuation token">]</span> <span class="operator token">=</span> <span class="keyword keyword-new token">new</span> <span class="token class-name">ServiceCtx</span><span class="punctuation token">(</span>serviceName<span class="punctuation token">)</span><span class="punctuation token">;</span><br/>   <span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_dictSvcCtx<span class="punctuation token">[</span>serviceName<span class="punctuation token">]</span><span class="punctuation token">.</span>m_databaseName <span class="operator token">=</span> pr<span class="punctuation token">.</span>m_databaseName<span class="punctuation token">;</span><br/>  <span class="punctuation token">}</span><br/><span class="punctuation token">}</span>

The "PR" here is an instance of OracleInternal.ServiceObjects.OracleConnectionImpl which get's its "ServiceName" apparently from some session properties:

<span class="keyword token keyword-internal">internal</span> <span class="keyword keyword-override token">override</span> <span class="keyword keyword-string token">string</span> ServiceName<br/><span class="punctuation token">{</span><br/>  <span class="keyword keyword-get token">get</span><br/>  <span class="punctuation token">{</span><br/>   <span class="keyword keyword-string token">string</span> str <span class="operator token">=</span> <span class="punctuation token">(</span><span class="keyword keyword-string token">string</span><span class="punctuation token">)</span> <span class="keyword token keyword-null">null</span><span class="punctuation token">;</span><br/>   <span class="keyword keyword-if token">if</span> <span class="punctuation token">(</span><span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_sessionProperties <span class="operator token">!=</span> <span class="keyword token keyword-null">null</span><span class="punctuation token">)</span><br/>   <span class="punctuation token">{</span><br/>   <span class="keyword keyword-if token">if</span> <span class="punctuation token">(</span><span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_sessionProperties<span class="punctuation token">.</span><span class="token function">ContainsKey</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="keyword keyword-object token">object</span><span class="punctuation token">)</span> <span class="string token">"AUTH_SC_SERVICE_NAME"</span><span class="punctuation token">)</span><span class="punctuation token">)</span><br/>  str <span class="operator token">=</span> <span class="punctuation token">(</span><span class="punctuation token">(</span><span class="keyword keyword-string token">string</span><span class="punctuation token">)</span> <span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_sessionProperties<span class="punctuation token">[</span><span class="punctuation token">(</span><span class="keyword keyword-object token">object</span><span class="punctuation token">)</span> <span class="string token">"AUTH_SC_SERVICE_NAME"</span><span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="token function">ToLowerInvariant</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span><br/>   <span class="punctuation token">}</span><br/>   <span class="keyword keyword-else token">else</span> <span class="keyword keyword-if token">if</span> <span class="punctuation token">(</span><span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_proxySessionProperties <span class="operator token">!=</span> <span class="keyword token keyword-null">null</span> <span class="operator token">&&</span> <span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_proxySessionProperties<span class="punctuation token">.</span><span class="token function">ContainsKey</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="keyword keyword-object token">object</span><span class="punctuation token">)</span> <span class="string token">"AUTH_SC_SERVICE_NAME"</span><span class="punctuation token">)</span><span class="punctuation token">)</span><br/>  str <span class="operator token">=</span> <span class="punctuation token">(</span><span class="punctuation token">(</span><span class="keyword keyword-string token">string</span><span class="punctuation token">)</span> <span class="keyword keyword-this token">this</span><span class="punctuation token">.</span>m_proxySessionProperties<span class="punctuation token">[</span><span class="punctuation token">(</span><span class="keyword keyword-object token">object</span><span class="punctuation token">)</span> <span class="string token">"AUTH_SC_SERVICE_NAME"</span><span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="token function">ToLowerInvariant</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span><br/>   <span class="keyword keyword-return token">return</span> str<span class="punctuation token">;</span><br/>  <span class="punctuation token">}</span><br/><span class="punctuation token">}</span>

Turned out (after a really long search) that the archivelog ran out of space (alert.log showed "ORA-19815: WARNING: %s of %s bytes is %s%% used, and has %s remaining bytes available. Cause: DB_RECOVERY_FILE_DEST is running out of disk space." earlier and it seems that now the remaining space was now depleted.

Which means that apparently the Oracle server doesn't provide these "session properties" in this case and it seems the code in Oracle Managed ODP.Net is not prepared for that situation.

Despite this, SQL Developer was able to connect to the database (so at first it didn't seem like a server issue). But by default our application uses a connection pool, and it seems the "ServiceName" acts as a key for a connection pool dictionary and since no "ServiceName" was provided we got this exception.

I think this situation should be handled in some better way, not just by throwing an ArgumentNullException (which is actually thrown be the generic dictionary that managed the connection pool). Maybe the client (OracleConnectionImpl or some other class) can check whether it got the expected values like session properties from the Oracle server. And then throw a specific exception if not. Or maybe there's a better way to recognize that the Oracle server has an issue? I don't know...

Not sure if this forum is a good way to report this issue. Please let me now if I should file this somewhere else.

Thanks,

Markus

Best Answer

Answers

This discussion has been closed.