客户端终止,TiDB数据库不终止任务

Bug 反馈
长事务语句执行,客户端强制终止,但是数据库端未终止,且最终完成事务提交
【 TiDB 版本】6.3以及之前
【 Bug 的影响】影响跑批等

【可能的问题复现步骤】
create table A ;
sql_text = “insert into A select * from (复杂执行时间较长查询,便于模拟)”
在客户端执行sql_text,预计执行20分钟。
客户端强行终止sql_text的连接,该语句会在数据库中继续执行直到完成事务。

【看到的非预期行为】
客户端程序已超时终止,数据库端会继续执行直到事务成功完成。这样重复调起批次后有重复跑批风险。

【期望看到的行为】
客户端中断连接后,数据库端应立即中断正在运行的会话和终止语句。

如果使用客户端想要满足事务操作的话,应该有显示事务的方式来控制,不最后 commit 事务,则不会生效

谢谢,但这只是一种绕过的思路。

不是绕过, mysql client 默认是带隐式事务的,即使你操作mysql ,结果也是一样

我测试了db2,pg,mysql等数据库,在长事务(语句)执行时候客户端自己终止后,server端均立刻断开其会话(语句)。
但是tidb会执行完。这点不仅仅是在某些场景下影响客户端的判断,而且还会影响server的性能。
希望能够优化改进。

这个应该是tidb 的特殊点。 tidb暂时不支持使用 MySQL 命令行 ctrl+c 终止查询或连接。 TiDB 从 v6.1.0 起新增 Global Kill 功能(由 enable-global-kill 配置项控制,默认启用)。启用 Global Kill 功能时,KILL 语句和 KILL TIDB 语句均能跨节点终止查询或连接,且无需担心错误地终止其他查询或连接。当你使用客户端连接到任何一个 TiDB 节点执行 KILL 语句或 KILL TIDB 语句时,该语句会被转发给对应的 TiDB 节点。当客户端和 TiDB 中间有代理时,KILLKILL TIDB 语句也会被转发给对应的 TiDB 节点执行。

1 个赞

一般一个数据库对应一个应用系统,一个应用系统有多个应用系统模块(比如业务人员后台查询使用,客户交易,批量作业等,每一个模块不会单独划分2个负载均衡的tidb-server),当某一个功能模块有问题的时候我可以停止该模块来减少对数据库的全局影响。但是在tidb这里,当我停止这个模块后,其造成的慢语句可能导致长时间占用资源导致其它模块的语句性能下降(交易量下降但成功率没下降),如果因此我重启tidb-server来快速恢复那么我其它模块的成功率就会下降。

可以手工的kill 慢查询

这个客户端ctrl+c 方式中断语句(通过jdbc等应用程序连接也一样)在7.3版本中提供了:
https://docs.pingcap.com/zh/tidb/stable/release-7.3.0
对应的issue:Support CTRL-C or kill <connId> to kill a connection/query by implementing global connection IDs · Issue #8854 · pingcap/tidb · GitHub
所以在7.5这个LTS版本中已经可用了,经过测试在应用程序侧断开后,数据库会同时杀掉语句释放资源 【强!!!】
这两天还因为这个触发了一个故障,简单来说是:应用写的一个复杂查询语句执行时间较长,应用侧设置了超时机制,断开后重复执行导致在数据库侧发生了堆积,导致数据库卡顿,虽然有其它应对措施,但是没有一个能比应用断开自动释放数据库资源来的更香!点个赞!!!

1 个赞

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。