数据库连接串问题

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。

  • 【TiDB 版本】:5.7.25-TiDB-v4.0.0-rc
  • 【问题描述】:

若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出打印结果,请务必全选并复制粘贴上传。

很奇怪的问题,使用C#程序连接TIDB数据库,连接串如下:

Database=test;Data Source=127.0.0.1;User Id=root;Password=123456;pooling=true;CharSet=utf8;port=4000;Allow User Variables=True

如上连接时,程序执行含groupby的语句会提示

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘test.c_date’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

如果将连接串中的CharSet=utf8;去掉,改成如下连接串:

Database=test;Data Source=127.0.0.1;User Id=root;Password=123456;pooling=true;port=4000;Allow User Variables=True

相同语句就不会报错。同时,直接在tidb中运行语句,也不会报错。

1 个赞
  1. 可以测试下,不通情况下的 tidb 中 sql_mode 值是否相同吗?
  2. select @@sql_mode , tidb 中执行sql 查询

是这样的,数据库是同一个数据库,只有一个数据库。

只是我用程序去连接数据库,然后连接的时候加上CharSet=utf8就报groupby错误,不加就正常。不通过程序,直接在数据库中执行,也不报错。

我看文档是4.0版本有字符集调整,但是没看明白,所以发出来问问。3.0版本的时候,加上CharSet=utf8这个不报错,现在tidb升级到4.0了,报错了。所以我发个帖子问问。

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

数据库字符集是utf8mb4 排序规则是utf8mb4_bin

  1. 我可能没有描述清楚,麻烦先帮忙确认下,添加 CharSet=utf8 和 不添加 CharSet=utf8 时, 查看 sql_mode 是否一致?

  2. 查询报错的sql是否方便发送,麻烦同时发送建表语句,多谢

1、这个意思是让我用程序通过字符串去获取sql_model么?我觉得通过不同工具连接一个数据库,数据库的参数应该不会变吧。 我试试。

2、稍等,我先试试1

1、sql_mode是一样的。

添加CharSet=utf8 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

不添加CharSet=utf8 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

数据库查询 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

2、第一步的测试就是用下面的语句进行的测试

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;

CREATE TABLE tb_test ( c_born_date datetime(0) NULL DEFAULT NULL, c_note varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT ‘’ ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

insert into tb_test(c_born_date,c_note) select now(),’’

SELECT DATE_FORMAT(c_born_date,’%Y%m’) ‘Key’,count(1) ‘Value’ from tb_test GROUP BY DATE_FORMAT(c_born_date,’%Y%m’)

刚才试了一下,在程序连接串中添加CharSet=utf8时,

报错: SELECT DATE_FORMAT(c_born_date,’%Y%m’) ‘Key’,count(1) ‘Value’ from tb_test GROUP BY DATE_FORMAT(c_born_date,’%Y%m’)

不报错: SELECT c_born_date ‘Key’,count(1) ‘Value’ from tb_test GROUP BY c_born_date

我觉得重点放在v3.0和v4.0程序集的处理上有什么不同,我看v4.0说明中有关于程序集的说明,但是没看明白。

v3.0中的说明:

注意:

  • TiDButf8 被当做成了 utf8mb4 来处理。
  • 每种字符集都对应一个默认的 Collation,当前有且仅有一个。

v4.0中就没有看到类似的说明。

我刚试了一下,将连接串改为CharSet=utf8mb4;就不报错了。看来是4.0不支持utf8了。

麻烦内部确认一下,我这边需要一个官方答复去做说明。谢谢。

@Kongdom 你好我是 TiDB 这边的研发同学,问题原因是 4.0 在支持更多 collation 时,引入了一个 bug,导致 select field 里面 DATE_FORMAT(c_born_date,’%Y%m’) 和 group by 里面 DATE_FORMAT(c_born_date,’%Y%m’) 他们的 collation 不同,最终造成了这个问题。

在 4.0.0-rc.1 及其之后的版本已经 fix 了,可以尝试升级解决。 PR 我暂时没找到,稍后找到了再贴一下。

好的,谢谢

:ok_hand:

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