长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 5 日 13:31
1
【 TiDB 使用环境】生产环境
【 TiDB 版本】v5.3.0
【复现路径】客户端语言:go语言,发起程序,间隔一段时间,执行下面这条SQL,前后返回的数据量不一致。
SELECT order_id
,agent_tx_no
,paid_amount
,pay_time
,recon_time
FROM pay_order
WHERE pay_time > ‘1718899199’ AND pay_time < ‘1718985600’ AND status = ‘3’ AND channel_id IN (‘9’,‘31’,‘122’,‘126’,‘132’,‘136’,‘179’,‘180’,‘181’,‘182’,‘183’,‘186’,‘118’,‘119’,‘229’) ORDER BY id desc;
【遇到的问题:问题现象及影响】
【资源配置】进入到 TiDB Dashboard -集群信息 (Cluster Info) -主机(Hosts) 截图此页面
【附件:截图/日志/监控】
一、表结构
二、程序运行日志、慢日志:
1、正确的数据量为 133225 条
2、错误的数据量为 501 条
三、执行计划:执行计划走的tikv节点,paytime(pay_time)索引,已排除隐式转换导致的
小龙虾爱大龙虾
(Minghao Ren)
2024 年7 月 5 日 13:41
2
还能复现吗,结果错误和结果正确的执行计划文本格式拿一下呗
长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 5 日 14:07
3
1、可以复现,程序一直在运行的时候,偶尔会有几条SQL执行结果集是错误的,返回501条。
2、拿这条SQL,手工在tidb上反复执行,返回结果集又是正确的
3、下面的附件是在dashbord上粘贴出来的,对应时间点错误和正确的执行计划
错误的:
error_result_explain (6.3 KB)
正确的:
normal_result_explain (5.5 KB)
1 个赞
长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 5 日 14:29
5
错误的执行计划,为什么会走TopN计算,从每个 TiKV Region 只返回一行数据给 TiDB,那岂不是丢数据了?
小龙虾爱大龙虾
(Minghao Ren)
2024 年7 月 5 日 14:30
6
TOP N 不知道哪里来的 ,拿着 dashboard 里的执行计划的 plan_degest 去 slow query 找下,看有没有,有的话把 slow query 中的信息发出来
长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 5 日 14:37
7
slow query都是一样的
SELECT order_id
,agent_tx_no
,paid_amount
,pay_time
,recon_time
FROM pay_order
WHERE pay_time > ? AND pay_time < ? AND status = ? AND channel_id IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY id desc [arguments: (“1718899199”, “1718985600”, “3”, “9”, “31”, “122”, “126”, “132”, “136”, “179”, “180”, “181”, “182”, “183”, “186”, “118”, “119”, “229”)];
slow_query.sql (3.2 KB)
小龙虾爱大龙虾
(Minghao Ren)
2024 年7 月 5 日 14:44
8
去 dashboard 里查查,看看有没有可能应用执行过 sql_select_limit 相关语句,别的真的不知道了
小龙虾爱大龙虾
(Minghao Ren)
2024 年7 月 5 日 14:48
9
哈喽沃德
2024 年7 月 6 日 04:06
10
应用不好保障的吧,万一框架里还有其他穿参,你应该拿同一sql去数据库窗口执行一下。
1 个赞
dba-kit
(张天师)
2024 年7 月 6 日 13:55
11
我建议你用ADMIN CHECK TABLE pay_order;
校验一下是不是主表和索引不一致
1 个赞
长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 8 日 02:04
12
没有执行过sql_select_limit语句,在程序里面会打印执行的完整SQL,异常SQL和正常SQL的digest都是一样的
长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 8 日 02:05
13
拿的是同一个SQL执行的,重复执行,返回的都是正确条数
长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 8 日 02:07
14
pay_order表数据量20亿左右,执行check操作会锁表吗,会消耗大量IO和CPU资源吗?
小龙虾爱大龙虾
(Minghao Ren)
2024 年7 月 8 日 02:53
15
请问是如何确认没有执行过 sql_select_limit 语句的?
小龙虾爱大龙虾
(Minghao Ren)
2024 年7 月 8 日 02:56
16
这个应该不是数据索引不一致问题,你看他那个执行计划,走的同一个索引
小龙虾爱大龙虾
(Minghao Ren)
2024 年7 月 8 日 02:59
17
在 github 上也没搜索到类似 bug (当然有可能是搜索的关键字不对),现在怀疑还是 sql_select_limit 可能行大,建议可以开 审计日志,或者 general 日志,或者把慢 sql 阈值调整为 0 ,等到复现后将该 session 从连接上后的所有 SQL 都拿出来分析下
长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 8 日 03:02
18
1、应用程序开启debug日志,将执行的SQL完整打印输出,未发现有limit参数
2、慢日志中记录的SQL,返回错误结果的SQL和正确的SQL,是一样的,sql Digest 也是一样的
长了翅膀的猪
(Ti D Ber Lw Uz Vvsl)
2024 年7 月 8 日 03:08
19
应用程序切换到去查原生的MySQL pay_order表(TiDB 同步的上游),就没有出现结果集不一样的情况了
小龙虾爱大龙虾
(Minghao Ren)
2024 年7 月 8 日 03:21
20
应用程序日志反正我是不认的 ,我建议还是用上边提到的方法抓下日志(注意对业务影响)
看你这个场景很简单,就是一条 SQL 结果不一样,如果你能提供一个 demo ,稳定复现此问题,可以直接在 github 上提 issue
1 个赞