TiDB 的 graceful shutdown
作者: yiduoyunQ 原文来源:https://tidb.net/blog/f74f6a0a
现象
应用通过负载均衡链接 TiDB,使用 tiup cluster upgrade 滚动升级集群时,应用报 connection refused。以下基于 TiDB v6.1.2 分析该现象原因。
只看结论
当前(v6.1.2 及以下)TiDB 采用带 timeout 的 graceful shutdown 机制。
无论是否配置 graceful-wait-before-shutdown,滚动升级期间应用均会感知报错。
PR #37441 和 Issues #32110 会有优化,但彻底解决问题需要等 session manager 实现。
建议滚动升级操作在运维窗口期或业务低峰期实施,应用端增加错误重试机制。
TiDB graceful shutdown 流程
tiup cluster upgrade 通过发送 SIGTERM 信号给 TiDB 实现滚动升级重启,TiDB 接收 SIGTERM 信号后触发 graceful shutdown。
当前(v6.1.2 及以下) TiDB 处理 SIGTERM 信号时,判断 graceful 的结果会是 false,因此最终调用 cleanup 时会走到 TryGracefulDown,使用带 timeout(固定 15s)的 graceful shutdown 机制。
具体 graceful shutdown 流程如下:
TiDB 收到 SIGTERM 信号后,先切换为下线状态并关闭所有服务。
切换为 inShutdownMode 状态,此时当接收到新的链接请求时直接返回 500 报错。
等待 graceful-wait-before-shutdown 后,关闭所有服务,拒绝新的链接请求。
接着执行 cleanup 处理已建链请求
对未在事务中处于 idle 状态的链接,从 server 端尝试关闭链接。
其他情况的链接,每秒重新探测一次状态。
若超过 15s timeout 时间,最终 kill 所有链接。
graceful-wait-before-shutdown 的问题
默认 0s 的情况下,TiDB 收到 SIGTERM 信号后会立刻关闭所有服务,此时应用端通过负载均衡尝试建立新链接会报 connection refused。
通过配置 graceful-wait-before-shutdown 可以推迟关闭所有服务,让负载均衡的健康探测有窗口机会主动将 TiDB 节点摘除,但在时间窗口内应用端通过负载均衡尝试建立新链接仍会报 Internal Server Error 500 的错误。
因此 graceful-wait-before-shutdown 没有解决根本问题,无论配置与否应用端都会报错,直到负载均衡的健康探测将 TiDB 节点摘除或 TiDB 重新启动恢复服务。
当前正在做的优化
PR #37441 将 graceful shutdown 机制更改为无限等待(最新的 v6.3.0 DMR 已带上了该 PR),Issues #32110 中解决 ongoing txn 的问题。
优化后可以解决:
graceful shutdown 超过 15s 直接 kill,不够优雅。
目前每秒重新探测一次链接状态,当链接上持续不断执行事务时,几乎不可能探测到链接处于不在事务的 idle 状态。
无法解决:
长时间执行的批量大事务。
graceful-wait-before-shutdown 的问题。
中长期规划:
通过增加一层 session manager 彻底解决问题。
建议
tidb 滚动升级操作建议放在运维窗口或业务低峰期实施,应用端增加错误重试机制。
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/c4dfaea1df3a8027faf8906c3】。文章转载请联系作者。
评论