tidb sql查询数据不正确,条件不过滤。

【概述】 场景 + 问题概述
tidb 查询数据有问题,见如下两条sql对比;
第一条sql可以查出来id为 271535 并且 next_check_time 也是大于1664360160 的记录。

正确的查询结果如下:

表结构如下
CREATE TABLE temp_order_job (
id bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(4) */,
seller_id varchar(100) NOT NULL DEFAULT ‘’,
region varchar(20) NOT NULL DEFAULT ‘’ COMMENT ‘’,
marketplace_ids varchar(500) NOT NULL DEFAULT ‘’ COMMENT ‘’,
start_timestamp int(10) NOT NULL DEFAULT ‘0’ COMMENT ‘’,
end_timestamp int(10) NOT NULL DEFAULT ‘0’ COMMENT ‘’,
request_status int(10) NOT NULL DEFAULT ‘0’ COMMENT ‘’,
api_type varchar(20) NOT NULL DEFAULT ‘sp’ COMMENT ‘’,
gmt_modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘’,
gmt_create datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘’,
next_check_time int(10) NOT NULL COMMENT ‘’,
PRIMARY KEY (id) /*T![clustered_index] CLUSTERED */,
KEY idx-request_status-next_check_time (request_status,next_check_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin /*T![auto_rand_base] AUTO_RANDOM_BASE=1260001 */

【业务影响】
数据查询不正确

【TiDB 版本】
V5.4.2

不会这么巧,做过br还原吧

可以测试一下第一句,子查询里也加上id的条件试试

这两条查询结果都是可以复现的吗?不会是两条SQL执行前后数据被修改了吧?
这个next_check_time列是个时间,应该是有意义的吧?会不会在某个时间这一行的状态被修改了?

看命名带着temp,不会真的是临时表,经常变化的吧

没有那么快更新 昨天和今天反复查询现象都一样

括号里加上id条件,也是这种现象么?

有没有做过br还原?

之前出现这种情况,排除bug和sql写法问题,主要两个原因,
1、向非空库还原数据,导致取数混乱
2、有其他线程在频繁更新表数据


这个SQL的执行结果中,id=271535的行,request_status的值能看到吗?是1还是2?
要不要确认下,到底是哪个查询条件导致的上面两条SQL的查询结果中request_status的值不同的?

你上面那条是order by id 下面没有带order by

结果值如下

正确的值如下

不太明白,下面那条数据 都id=271535 了 为什么还要order by 呢?我们需要验证的是 为什么两条sql查询的值不一样,这个是否是bug,还是用法问题。

select id,next_check_time,request_status From temp_order_job WHERE request_status = 1 AND next_check_time<1664360160 and id=271535;
这样查一下看看呢?
这tidb里不会有两个数据库都有这个表吧?我看上面两条SQL没指定表的数据库名…

3月份使用过br迁移到这个库的,当时迁移的时候是目标是新集群,没有任何业务数据。

我指定库查询的 而且集群只有这一个表…

查不出的 因为id 271535 这个数据正确的值是request_status =2

select count() from (select id,next_check_time,request_status From temp_order_job WHERE request_status = 1 AND next_check_time<1664360160 order by id limit 50);
select count(
) from (select id,next_check_time,request_status From temp_order_job WHERE request_status = 1 AND next_check_time<1664360160);
select count(*) from (select id,next_check_time,request_status From temp_order_job WHERE request_status = 1 AND next_check_time<1664360160 order by id );
看看查询结果,哪个有问题?

结果如下

select * from (select id,next_check_time,request_status From temp_order_job WHERE request_status = 1 AND next_check_time<1664360160 order by id ) t where t.id=271535;
这个有结果吗?
要是没有结果,看着就是limit和order by一起使用的问题…
select * from (select * from (select id,next_check_time,request_status From temp_order_job WHERE request_status = 1 AND next_check_time<1664360160 order by id ) t limit 50) tt where tt.id=271535;
–可以再考虑下,下面的SQL需要执行看看不?limit调整到查询出所有数据。。。
select * from (select * from (select id,next_check_time,request_status From temp_order_job WHERE request_status = 1 AND next_check_time<1664360160 order by id ) t limit 37000) tt where tt.id=271535;

第一条没有结果的,应该是order by 和 limit一起的问题

第二条和第三条的结果一样

单独执行第一条sql里面的子查询 会查出271535这条数据:sweat:。