MySQL连接卡在Sleep状态是因应用未正确关闭连接且服务端wait_timeout与连接池配置不匹配所致;需确保close()调用、max-lifetime<wait_timeout、启用连接验证及事务规范管理。MySQL 连接卡在 sleep 状态不释放,查 show processlist 一堆 Sleep这是典型的连接未正确关闭 + 服务端超时配置不匹配导致的积压。MySQL 服务端默认 wait_timeout=28800(8 小时),但应用层如果用连接池却从不显式 close() 或没配空闲回收,连接就会一直挂着,直到服务端主动 kill------而这个 kill 恰好发生在你执行下一条语句前,报错 Lost connection to MySQL server during query 或 MySQL server has gone away。实操建议:先确认当前值:SHOW VARIABLES LIKE 'wait_timeout';,开发环境可临时调低到 60 秒快速暴露问题应用代码里所有 Connection、Statement、ResultSet 必须在 finally 或 try-with-resources 中 close(),漏一个就可能 leak别依赖"连接池会自动清理"------HikariCP 默认 connection-timeout=30000,但空闲连接存活时间由 idle-timeout 控制,默认 10 分钟,仍远大于常见业务响应时间HikariCP 的 max-lifetime 和 MySQL wait_timeout 必须错开如果两者相等或 max-lifetime ≥ wait_timeout,连接池会把一个已被 MySQL 关闭的连接再分配出去,下次使用直接抛异常。这不是 bug,是设计如此:连接池只管"自己没过期",不管"数据库侧是否还接受它"。实操建议:max-lifetime 必须严格小于 wait_timeout,建议留 30--60 秒缓冲,比如 MySQL 设为 3600(1 小时),HikariCP 就设 3500同时打开 connection-test-query=SELECT 1(MySQL 8.0+ 推荐用 isValid())和 test-on-borrow=true,但注意这会增加每次获取连接的延迟更轻量的做法是关掉 test-on-borrow,改用 keepalive-time=30000(每 30 秒发一次 SELECT 1 检活),配合 validation-timeout=3000Spring Boot + MyBatis 下,事务未结束就 return 导致连接不归还常见于 Controller 层直接返回 ResponseEntity<List>,但 Service 方法加了 @Transactional,MyBatis 的 SqlSession 绑定在线程上,return 后方法虽结束,事务还没提交/回滚,连接就被卡住------尤其遇到流式查询、分页 count 查询后紧跟 list 查询时特别容易触发。 跃问 跃问是由阶跃星辰开发的免费AI智能问答助手,随时帮你智能搜索、高效阅读、识图理解、和你畅聊感兴趣的话题。
相关推荐
IvorySQL8 小时前
PostgreSQL 日报|逻辑复制行过滤致数据丢失(8 月 21 日)重生之我是Java开发战士8 小时前
【Java EE】事务与事务的传播机制润乾软件8 小时前
Trae+SQLazy 编写复杂 SQL 实践会编程的吕洞宾8 小时前
Redis大Key拖垮线上?排查定位与治理实战ltl9 小时前
WiredTiger History Store:文档库里的第三种 MVCC码农阿豪9 小时前
若依启动突然报 Redis MISCONF?一次从应用报错到磁盘爆满的完整排查记录ltl9 小时前
SQLite 查询计划器:没有 ANALYZE 时靠什么猜ltl9 小时前
Redis maxmemory 策略:近似 LRU/LFU 与 MEMORY DOCTORleisoo80979 小时前
ig50数据落盘ClickHousevsTimescaleDBvsDuckDB实测对比 IG50免费开源股票数据API接口卷无止境9 小时前
FastAPI 的 Metadata 到底是什么,又牵动了哪些核心概念