分区大表执行 max(索引列) 报错或无返回

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【 TiDB 使用环境】
生产环境,版本5.7.25-TiDB-v6.1.0

【概述】 场景 + 问题概述
背景说明:该表总行数有约500亿行所有,按天分区,每个分区1亿多行。

分区表结构
主键索引: PRIMARY KEY ( dt , doc_id ) /*T![clustered_index] NONCLUSTERED */,
PRIMARY KEY ( dt , doc_id ) /*T![clustered_index] NONCLUSTERED */,
KEY updatetime ( updatetime ),
KEY newdate ( newdate )
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![placement] PLACEMENT POLICY= storeonssd */
PARTITION BY RANGE (UNIX_TIMESTAMP( dt ))
(PARTITION p20210601 VALUES LESS THAN (1622563200),
…)

【背景】 做过哪些操作
对该表执行max查询,其中dt为时间字段,是主键索引的左边第一个字段:
select max(dt) from logoutrole;

【现象】 业务和数据库现象
【问题】 当前遇到的问题
1.执行查询,报错 或长时间无返回,报错时信息如下:
mysql> select max(dt) from logoutrole;
ERROR 1105 (HY000): other error: Coprocessor task terminated due to exceeding the deadline
mysql>

2.执行计划

【业务影响】
无法正确获取内容

【TiDB 版本】
v6.1.0

【应用软件及版本】
5.7.25-TiDB-v6.1.0

从你之前的帖子来看 是因为 TOP 下推到了 全部 partition

从 执行计划看 task 任务最长 45s task 数量 11228 。并且看你的 Placement rule 有 冷热之分。所以 整体查询任务会非常慢,逻辑上是预期内的

最直接有效优化建议强制 使用分区裁剪
譬如 增加 where dt > ‘2022-06-01 00:00:00’

强制 使用分区裁剪,也就是强制业务方在where条件里加上分区字段的条件过滤吧,这个就需要业务方修改代码了。有没有其他不用改业务代码,在服务端就可以优化的方式呢

https://github.com/pingcap/tidb/pull/36610 有 PR 合到 master 了,官方定义为 BUG。

1 个赞

嗯,预计是什么时候发布优化该问题,有plan吗

在分区剪裁规则优化前,是没有的。
正常 6.3 会发布 ,但会争取 6.1.1 合入。预计 9月中前会发出

1 个赞

好的,感谢解答:+1:

coprocessor是有查询超时时间限制吗?

另一个类似的问题:range分区表order by 索引列limit 1 长时间未返回

cop没有 超时 但有 excute time out session 变量和hint 可以控制sql 超时

mysql> select max(dt) from logoutrole;
ERROR 1105 (HY000): other error: Coprocessor task terminated due to exceeding the deadline

那这个报错代表什么意思?原因是什么?因为数据量太大cop线程崩溃?

应该是 region 太多 load region 的时候超时了

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