mysql c++ connector连接超时需分两层设置:连接建立阶段用url参数connect-timeout=5(连字符,非下划线),服务端空闲超时由wait_timeout控制,客户端无法直接设,仅能通过set session wait_timeout=n临时调整。

MySQL C++ Connector 连接超时参数怎么设才有效
MySQL Connector/C++ 默认不启用连接超时控制,connect_timeout、wait_timeout、interactive_timeout 这些参数必须显式传给服务端,客户端库本身不会自动重试或中断阻塞连接。
关键点在于:超时分两层——建立连接阶段的 connect_timeout(单位秒),和已建立连接后空闲等待的 wait_timeout(服务端配置,单位秒)。后者无法由客户端直接设置,只能通过 SET SESSION wait_timeout = N 临时调整,且受 MySQL 全局变量限制。
-
connect_timeout要在连接字符串里加:"tcp://localhost:3306?connect-timeout=5"(注意是连字符,不是下划线) - 使用
sql::mysql::MySQL_Driver::newInstance()创建驱动后,调用driver->setOption("CONNECT_TIMEOUT", "5")无效 —— 这个 API 在新版 Connector/C++ 8.0+ 已废弃,仅旧版部分支持 - 若用
createConnection()传 URL,必须确保 URL 解析器能识别参数;常见错误是写成?connect_timeout=5(下划线),实际应为connect-timeout
连接断开后如何安全重试而不卡死
MySQL 连接可能因网络抖动、防火墙回收、服务端 kill 或 wait_timeout 触发而静默断开,此时执行 stmt->execute() 会抛出 sql::SQLException,错误码通常是 CR_SERVER_LOST(2013)或 CR_CONN_HOST_ERROR(2003)。
不能依赖 connection->isValid() 判断——它在某些版本中只是检查指针非空,不真正发心跳包;也不能在每次操作前都 ping(性能差且可能引入竞态)。
- 推荐做法:捕获
sql::SQLException,检查e.getSQLState().compare("08S01") == 0(SQLSTATE 08S01 表示通信链路失败)或e.getErrorCode() == 2013 - 重连前先
delete conn(Connector/C++ 不自动释放底层 socket),再重新driver->connect(...);不要复用已断开的sql::Connection*指针 - 重试最多 1–2 次,避免雪崩;建议加指数退避,比如第一次等 100ms,第二次等 300ms
长连接场景下如何主动保活防止被服务端踢掉
MySQL 默认 wait_timeout = 28800(8 小时),但很多生产环境设为 300–600 秒。如果应用连接池长期持有连接却无查询,连接会被服务端强制关闭,下次使用时才暴露问题。
单纯靠 SET SESSION wait_timeout 不可靠:它只影响当前 session,且不能超过全局 max_wait_timeout;更稳的方式是定期发送轻量心跳。
- 每 240 秒(比服务端
wait_timeout小至少 60 秒)执行一次conn->createStatement()->execute("SELECT 1") - 心跳必须用独立
sql::Statement*,避免干扰业务事务;执行后立即delete stmt - 心跳失败即视为连接失效,按上一节逻辑重建连接,而不是继续重试
- 不要用
PING命令(Connector/C++ 未暴露该接口),SELECT 1是最兼容的保活方式
连接池里重连失败怎么办
连接池(如自建 pool 或第三方库)中某个连接失效后,若重连也失败(比如 DB 宕机、权限变更、DNS 失效),继续让业务线程阻塞等待会导致级联超时。
核心原则:连接池应在获取连接时完成“可用性验证”,而不是把烂连接交给业务代码。
- 从池中取出连接后,先执行一次
SELECT 1,成功才返回;失败则标记该连接为 invalid,丢弃并尝试创建新连接 - 若新建连接也失败,池应快速失败(fail-fast),抛出明确异常如
std::runtime_error("DB unreachable"),而不是无限重试 - 连接池最大重试次数建议设为 1,因为多次重连大概率是系统性故障,应交由上层做降级或告警
重连逻辑本身不复杂,难的是状态清理和资源释放时机——sql::Connection 析构时若底层 socket 已关闭,某些版本 Connector/C++ 会 crash;务必确保 delete 前连接处于可关闭状态,或捕获析构异常兜底。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











