You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用负载均衡时MySQL .NET Connector引发多类异常问题排查

问题描述

我们有一个基于.NET Framework 4.6的ASP.NET项目,使用8.0.29版本的MySQL.Data NuGet包,连接MySQL集群中的多个数据库。MySQL连接器支持通过逗号分隔多主机名实现流量负载均衡,该配置在测试环境运行正常,但在流量更大的生产环境中,Windows Server事件查看器出现大量异常。单独连接集群内任一数据库均无问题,仅多主机同时配置时触发异常。

连接字符串示例

server=example1.com,example2.com,example3.com;port=25060;uid=username;pwd=password;database=database;pooling=false;Allow User Variables=True;CharSet=utf8

注:pooling设为false是因连接池引发其他独立问题

出现的异常

异常1:MySqlException

Exception type: MySqlException
    Exception message: Unable to connect to any of the specified MySQL hosts.
   at MySql.Data.MySqlClient.NativeDriver.<>c.<Open>b__40_0(Exception ex)
   at System.AggregateException.Handle(Func`2 predicate)
   at MySql.Data.MySqlClient.NativeDriver.Open()
   at MySql.Data.MySqlClient.Driver.Open()
   at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
   at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
   at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
   at MySql.Data.MySqlClient.MySqlPool.GetConnection()
   at MySql.Data.MySqlClient.MySqlConnection.Open()

异常2:InvalidOperationException

Exception type: InvalidOperationException
    Exception message: Collection was modified; enumeration operation may not execute.
   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.KeyCollection.Enumerator.MoveNext()
   at System.Data.Common.DbConnectionStringBuilder.get_ConnectionString()
   at System.Data.Common.DbConnectionStringBuilder.set_ConnectionString(String value)
   at MySql.Data.MySqlClient.MySqlConnection.Open()

异常3:SocketException

Exception type: SocketException
    Exception message: No such host is known
   at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult)
   at System.Net.Dns.EndGetHostAddresses(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)

异常4:NullReferenceException

Exception type: NullReferenceException
    Exception message: Object reference not set to an instance of an object.
   at MySql.Data.Failover.FailoverManager.AttemptConnection(MySqlConnection connection, String originalConnectionString, String& connectionString, Boolean mySqlPoolManager)
   at MySql.Data.MySqlClient.MySqlConnection.Open()

疑问

该问题原因是什么?是否为我们的配置操作有误?


问题分析与解决方案

核心原因

并非配置错误,而是MySQL.Data 8.0.29版本的多主机负载均衡/故障转移逻辑存在线程安全缺陷,高并发场景下会触发多种异常:

  • InvalidOperationException:连接字符串构建器的字典被多线程并发修改时触发枚举冲突,属于典型的非线程安全容器并发访问问题。
  • NullReferenceException:FailoverManager在高并发下内部状态未正确初始化或被并发修改,导致空引用。
  • SocketException/MySqlException:并发场景下DNS解析或连接尝试逻辑被打乱,出现主机无法解析或全部连接失败的情况。

另外,pooling=false的配置会加剧问题:关闭连接池后,每次请求都要创建新连接,并发请求量直接等同于连接创建的并发量,大幅提升了触发线程安全问题的概率。测试环境流量低、并发连接少,因此未暴露该缺陷。

解决步骤

  1. 升级MySQL.Data包:官方在8.0.30及后续版本修复了多主机场景下的线程安全问题,优先升级到最新稳定版。
  2. 评估恢复连接池的可能性:如果原连接池的独立问题可通过调整参数(如max pool size、connection timeout等)解决,建议恢复pooling=true——连接池能减少连接创建的并发量,降低异常触发概率,同时提升性能。
  3. 临时应急方案:若暂时无法升级包,可在代码中对MySqlConnection.Open()添加全局锁,强制串行化连接创建逻辑,但这会牺牲部分并发性能,仅作为临时过渡方案。

内容的提问来源于stack exchange,提问作者Walance

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:35:18