Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to query the current size of the MySQL's .Net connector's connection pool?

Tags:

c#

mysql

Is there a programmatic way to find the current number of open connections to the database that are being maintained by the .Net connector/MySql.Data.dll?

I'm interested in collecting this information within the same program as the library is used.

like image 936
chillitom Avatar asked Feb 19 '13 17:02

chillitom


2 Answers

Connection pooling is performed on the client side. To get access to it, you'll need to use reflection to get to the MySqlPoolManager and MySqlPool classes, which are both internal to the MySql.Data assembly.

Essentially, you'll want to use reflection to get to the pool. Here's how:

Assembly ms = Assembly.LoadFrom("MySql.Data.dll");
Type type = ms.GetType("MySql.Data.MySqlClient.MySqlPoolManager");
MethodInfo mi = type.GetMethod("GetPool", BindingFlags.Static | BindingFlags.Public);
var pool = mi.Invoke(null, new object[] { new MySqlConnectionStringBuilder(connString) });

You'll notice that you have to pass in a MySqlConnectionStringBuilder object. It creates a separate pool for each connection string, so use the same connection string you use in your app (it needs to be completely identical).

You can then access the private pool fields and properties (again, using reflection), to get the information you need. In particular, the "available" field and the "NumConnections" properties are probably what will be of interest to you. There's also the "idlePool" (a Queue<>) and the "inUsePool" (a List<>) which you can access as well, particularly the counts.

like image 77
Pete Avatar answered Oct 01 '22 01:10

Pete


Thanks to Petes answer to this question and this other answer I was able to build the below function:

    /// <returns>totalAvailable, inUseCount, idleCount</returns>
    public int[] GetPoolStatsViaReflection(MySqlConnectionStringBuilder connectionStringBuilder)
    {
        var asm = typeof(MySqlConnectionStringBuilder).Assembly;
        var poolManagerType = asm.GetType("MySql.Data.MySqlClient.MySqlPoolManager"); // internal sealed
        var poolType = asm.GetType("MySql.Data.MySqlClient.MySqlPool"); // internal sealed

        var pool = poolManagerType.InvokeMember("GetPool", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, null, new object[] { connectionStringBuilder });

        const System.Reflection.BindingFlags nonPublicInstanceField = System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
        var totalAvailable = (int)poolType.InvokeMember("available", nonPublicInstanceField, null, pool, new object[] { });
        // List<Driver>
        var inUsePool = (System.Collections.ICollection)poolType.InvokeMember("inUsePool", nonPublicInstanceField, null, pool, new object[] { });
        // Queue<Driver>
        var idlePool = (System.Collections.ICollection)poolType.InvokeMember("idlePool", nonPublicInstanceField, null, pool, new object[] { });

        return new[] {totalAvailable, inUsePool.Count, idlePool.Count};
    }
like image 28
NiKiZe Avatar answered Oct 01 '22 02:10

NiKiZe