ODP.NET のコネクションプール使用状況を確認する方法

タイトル通り。ODP.NETのアプリケーション上で生成したコネクションプールについて、アクティブなコネクション数やプールされているコネクションの合計数がどのくらいあるのかを確認するときは、パフォーマンスモニタを利用する必要があるので、その方法を記載する。

今回使用しているのは、Oracle Client 19c に付属する ODP.NET(4.122.19.1)の管理対象ドライバ。管理対象外ドライバの場合はやり方が若干異なるようなので注意。

開発者ガイド

事前準備

何も準備していない状況では、パフォーマンスモニタにはODP.NETのコネクションを監視するためのカウンタが表示されない。表示させるためには、ORACLE_HOME\ODP.NET\PerfCounters 配下のPowerShellスクリプトを事前に実行しておく必要がある。ドライバごとにスクリプトが用意されているので、管理対象ドライバの場合は管理者で起動したPowerShellで以下のように実行する。

PS E:\Apps\Oracle\client\ODP.NET\PerfCounters> .\register_odpm_perfmon_counters.ps1

セキュリティ警告
信頼するスクリプトのみを実行してください。インターネットから入手したスクリプトは便利ですが、コンピューターに危害を及ぼ
す可能性があります。このスクリプトを信頼する場合は、この警告メッセージが表示されないように、Unblock-File
コマンドレットを使用して、スクリプトの実行を許可してください。E:\Apps\Oracle\client\ODP.NET\PerfCounters\register_odpm_
perfmon_counters.ps1 を実行しますか?
[D] 実行しない(D)  [R] 一度だけ実行する(R)  [S] 中断(S)  [?] ヘルプ (既定値は "D"): R
ODP.NET, Managed Driver Performance Counter was registered successfullly.

すると、以下のように「ODP.NET, Managed Driver」配下にカウンタが追加される。

プログラム側の設定

プログラム側にもパフォーマンスモニタを利用するための設定を行う必要がある。

具体的には、App.configに以下のように必要な設定を入れ込む。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<configSections>
		<section name="oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.122.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342" />
	</configSections>
	<startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
	<oracle.manageddataaccess.client>
		<version number="*">
			<settings>
				<setting name="PerformanceCounters" value="4095"/>
			</settings>
		</version>
	</oracle.manageddataaccess.client>
</configuration>

valueに指定している4095は、全てのカウンタを有効化するという意味合い。

パフォーマンスモニタの設定

ここまで準備したら、実際にプログラムを起動した後にパフォーマンスモニタに必要なカウンタを追加する。プログラムを起動していないと、対象のインスタンスがカウンタに表示されない。

ちなみに、この時に使ったのは以下のコード。

using Oracle.ManagedDataAccess.Client;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConnectionPoolTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Parallel.For(0, 50, i =>
                {
                    try
                    {
                        OracleConnection con = new OracleConnection();
                        con.ConnectionString = "user id=testuser;password=testuser;" +
                        "data source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.12)(PORT=1521))" +
                        "(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=db19)));" +
                        "Min Pool Size=5;Max Pool Size=10;Connection Lifetime=100000;" +
                        "Connection Timeout=60;Incr Pool Size=5; Decr Pool Size=2";

                        con.Open();
                        Console.WriteLine("Connection Opened.");
                        Thread.Sleep(10000);
                        
                        con.Close();
                        Console.WriteLine("Connection Closed.");
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

コメント