EF Core配合Pomelo使用时出现SocketException(995)及MySQL空闲连接问题咨询
异常产生原因
1. 初始连接池耗尽、大量空闲连接问题
你最初遇到的MySqlConnector.MySqlException (0x80004005): Connect Timeout expired. All pooled connections are in use.错误,本质是应用没有正确释放数据库连接,导致连接池内的可用连接被占满,同时这些被占有的连接大多处于空闲状态,没有被归还给连接池复用。
最常见的触发场景包括:
- 没有对
MySqlConnection、DbContext等实现了IDisposable的数据库访问对象做释放,比如没有用using语句包裹,也没有手动调用Dispose()方法 - 存在长时间运行的数据库查询/事务,长期持有连接不释放
- 异步数据库操作没有正确添加
await关键字,导致连接被后台未完成的异步操作意外持有
2. 关闭连接池后出现命令超时的原因
你设置POOLING=FALSE之后,每次数据库操作都会新建一个TCP连接到MySQL,操作完成后直接销毁连接,完全绕过连接池复用逻辑:
- 频繁新建/销毁TCP连接会带来巨大的性能开销,还会占用大量系统端口资源,本身就会大幅拖慢数据库操作的速度
- 从异常堆栈可以看出超时出现在身份认证环节拉取用户角色的查询场景,说明高频请求下新建连接的开销已经超过了默认的命令超时阈值,才触发了IO中断异常
该方案完全是饮鸩止渴,只会让性能问题更严重,绝对不推荐生产环境使用。
MySQL空闲连接过多的最优处理方案
- 优先排查连接泄漏问题
检查所有数据库访问逻辑,确保DbContext、MySqlConnection都通过using语句自动释放,或者在依赖注入容器中注册为Scope/Transient生命周期,请求结束后自动销毁释放连接。同时排查有没有未await的异步数据库操作,避免连接被后台未完成的任务持有。 - 优化连接池配置,禁止关闭连接池
保留连接池开启的前提下,调整连接字符串的相关参数:# 调整最大连接数,根据你的MySQL实例支持的最大连接数设置,不要超过MySQL的max_connections配置 Max Pool Size=50 # 调整连接空闲超时时间,空闲超过该时长的连接会被自动回收,单位秒 Connection Idle Timeout=60 # 开启连接复用校验,避免返回给应用的是已经被MySQL端断开的无效连接 Connection Reset=true - MySQL端配合调整超时配置
在MySQL实例中调低wait_timeout和interactive_timeout参数,默认一般是8小时,可以调整为1小时,让MySQL端主动回收长时间空闲的连接,避免空闲连接堆积。 - 限制长事务/慢查询的执行时间
对执行时间超过阈值的慢查询做优化,避免长事务持有连接超过空闲回收时间。
内容的提问来源于stack exchange,提问作者Ryan Teh
相关产品推荐
相关产品推荐

