升级v7.1.0后sql执行异常

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:

【背景】 版本由v6.1.1 升级到 v7.1.0

【问题】 见截图, 升级前ok, 升级后报错 Incorrect arguments to LIMIT

【业务影响】 开发站测试,暂无大的影响

【TiDB 版本】 v7.1.0

【附件】 相关日志及监控

limit为啥要用BigDecimal呢?你把拼装后的sql打出来看看

1 个赞

这已经是完整的sql了, select REC_ID from ORIG.TB_A0013 limit ?

至于为什么要用BigDecimal , 应该是历史问题了,牵扯较多,暂时不大好改

看上去不应该出问题啊,select REC_ID from ORIG.TB_A0013 limit 10 你打断点调试下看看变量sql有啥特殊的吗?

直接用数字,不绑定参数是没问题的

执行查询时使用的参数不太行。拿出来手动执行看看

直接执行不带参数的语句是没有问题的
比如: select REC_ID from ORIG.TB_A0013 limit 10000

数据库开日志,看看这句数据库收到的什么

请教具体打开日志方法及查看方法,谢谢

这是ide端,你能查到tidb自身的日志么?

可以查到,请帮忙提供查询方法

set @@tidb_general_log = true;
然后看tidb.log就行默认位置/tidb-deploy/tidb-4000/log
,注意测试环境跑,别在生产环境随便试试

1 个赞

多谢,我这边是开发环境,明天试一下,有结果再反馈

最好应用连固定的tidb节点或者就留一个tidb 方便看日志

难道用bigdecimal到数据库会变成这样?
SELECT * FROM bilibili_user LIMIT 10.0;

结果出来了,和反馈到前端的报错一样,传入的参数看起来也正常

limit后面是? 参数没传对

不对,后面看是传了的,估计是新版本对这个类型要求更严格了。你把bigdecimal改成int对应的JAVA类试试

看了参数是没问题的, 如果把参数改为Integer,也是没问题的
新版本对类型严格,有什么官方说明吗? 否则我们也不知道其他还有什么需要注意的。
另外有了官方的说明,我们才能安排开发做针对性改造

我分别做了小数和字符串的测试,跟我上面猜测的差不多,果然是对类型要求更严格了。

在v6.4.0里面,都还是好的。

root[test]>select version();
+--------------------+
| version()          |
+--------------------+
| 5.7.25-TiDB-v6.4.0 |
+--------------------+
1 row in set (0.01 sec)

root[test]>
root[test]>PREPARE st FROM 'SELECT * FROM t limit ?';
Query OK, 0 rows affected (0.01 sec)

root[test]>SET @a='1';
Query OK, 0 rows affected (0.01 sec)

root[test]>EXECUTE st USING @a;
+---+------+
| a | b    |
+---+------+
| 1 | NULL |
+---+------+
1 row in set (0.01 sec)

root[test]>PREPARE st FROM 'SELECT * FROM t limit ?';
Query OK, 0 rows affected (0.01 sec)

root[test]>SET @a=1.0;
Query OK, 0 rows affected (0.01 sec)

root[test]>EXECUTE st USING @a;
+---+------+
| a | b    |
+---+------+
| 1 | NULL |
+---+------+
1 row in set (0.01 sec)

在v7.1.0里面就会有问题,直接报错:

-- int 传字符串

[root@127.0.0.1][test][02:10:39]> select version();
+--------------------+
| version()          |
+--------------------+
| 5.7.25-TiDB-v7.1.0 |
+--------------------+
1 row in set (0.00 sec)

[root@127.0.0.1][test][02:14:42]> PREPARE st FROM 'SELECT * FROM t1 limit ?';
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1][test][02:14:52]> SET @a='1';
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1][test][02:14:52]> EXECUTE st USING @a;
ERROR 1210 (HY000): Incorrect arguments to LIMIT

--换成小数同样有问题。

[root@127.0.0.1][test][02:14:52]> PREPARE st FROM 'SELECT * FROM t1 limit ?';
Query OK, 0 rows affected (0.01 sec)

[root@127.0.0.1][test][02:18:32]> SET @a=1.0;
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1][test][02:18:32]> EXECUTE st USING @a;
ERROR 1210 (HY000): Incorrect arguments to LIMIT

官方确实没看到相关说明。

让我想起像这种int类型变量,传入字符串的场景还是挺多的。
再次做了个测试,还好这种只是有个warning。

[root@127.0.0.1][test][02:18:33]> desc t1;
+-------+-------------+------+------+---------+-------+
| Field | Type        | Null | Key  | Default | Extra |
+-------+-------------+------+------+---------+-------+
| a     | int(11)     | YES  |      | NULL    |       |
| b     | int(11)     | YES  |      | NULL    |       |
| c     | varchar(10) | YES  |      | NULL    |       |
| d     | varchar(20) | YES  |      | NULL    |       |
+-------+-------------+------+------+---------+-------+
4 rows in set (0.00 sec)

[root@127.0.0.1][test][02:22:12]> 
[root@127.0.0.1][test][02:22:14]> PREPARE st FROM 'SELECT * FROM t1 where a=?';
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1][test][02:22:49]> SET @a='1';
Query OK, 0 rows affected (0.00 sec)

[root@127.0.0.1][test][02:22:49]> EXECUTE st USING @a;
+------+---------+-------+------------+
| a    | b       | c     | d          |
+------+---------+-------+------------+
|    1 | 3668850 | 095dc | 5dea14941a |
+------+---------+-------+------------+
1 row in set, 1 warning (0.04 sec)

[root@127.0.0.1][test][02:22:49]> show warnings;
+---------+------+-------------------------------------------------------+
| Level   | Code | Message                                               |
+---------+------+-------------------------------------------------------+
| Warning | 1105 | skip prepared plan-cache: '1' may be converted to INT |
+---------+------+-------------------------------------------------------+
1 row in set (0.00 sec)

2 个赞