TIDB版本升级为7.5, java执行带json的SQL结果和升级前不一致问题

【TiDB 使用环境】生产环境
【TiDB 版本】7.5
【操作系统】Centos7.9
【问题复现路径】TIDB版本原地版本5.1升级到7.5.3
【遇到的问题:问题现象及影响】
1)TIDB版本升级前5.1版本时, java代码中使用的是mysql5.1.42版本的驱动,ext_json->>‘%xxx’取出来的就是值(字符串或数字),但是访问升级后的7.5,取出来的结果是byte类型,导致代码逻辑变化。
2)研发尝试使用新的mysql驱动(8.0.33)来解决兼容问题,但是ext_json->>’%xxx’结果也byte类型。

求助问题:
**1)问题原因?**是TIDB升级后对json的处理不同了么?
2)简便的快速回滚方法。
因为此TIDB集群有很多java应用使用,逐个修改代码逻辑工作量较大。研发希望可快速回滚到原来的状态(ext_json->>‘%xxx’)结果是值,请问是否有好的方法?
【资源配置】
【复制黏贴 ERROR 报错的日志】
【其他附件:截图/日志/监控】

使用Python, 及原生的mysql 客户端,查询TiDB5.1/TIDB7.5结果都是相同的,不存在研发反馈的问题。

MySQL:

Python:
SQL="SELECT ‘10.8.5’ AS se_version,‘0’ AS se_city,a.modified_stime,‘business’ AS se_business_type,a.ext_json ->>‘$.data_type’ as data_type FROM tb_car_pool a LEFT JOIN resource_pool_merge.uniq_nlp_tags e ON a.object_uid=e.object_uid WHERE a.object_uid=‘52-4-656181’ AND a.recommend_used=1 AND a.biz_type=52 AND a.is_delete=0 AND e.object_uid IS NOT NULL AND a.recommend_time IS NOT NULL AND a.recommend_time<=CURRENT_TIMESTAMP AND date_add(CURRENT_TIMESTAMP,INTERVAL-30 DAY)< a.recommend_time "
cursor1.execute(SQL)
rows1 = cursor1.fetchone()
cursor2.execute(SQL)
rows2 = cursor2.fetchone()

rows1
{u’se_business_type’: u’business’, u’se_version’: u’10.8.5’, u’data_type’: u’1’, u’se_city’: u’0’, u’modified_stime’: datetime.datetime(2025, 6, 30, 17, 31, 45)}
rows2
{u’se_business_type’: u’business’, u’se_version’: u’10.8.5’, u’data_type’: u’1’, u’se_city’: u’0’, u’modified_stime’: datetime.datetime(2025, 6, 30, 17, 31, 45)}

最好是让研发提供下最小复现代码。。。。。

1 个赞
  1. <mysql-connector-java.version>5.1.38</mysql-connector-java.version>
    jdbcTemplate来自Spring-jdbc5.2.7

  2. connection = Objects.requireNonNull(jdbcTemplate.getDataSource()).getConnection();
    statement = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    Map<String, Object> item = convert.toMap(resultSet);
    if (item.get(“direction”) != null) {
    itemValue.put(“direction”, item.get(“direction”));

  3. sql:ext_json->>‘$.direction’ as direction

  4. jdbc:mysql://host:port/db?useUnicode=true&characterEncoding=UTF-8&useSSL=false&tinyInt1isBit=false&yearIsDateType=false&zeroDateTimeBehavior=CONVERT_TO_NULL

https://docs.pingcap.com/zh/tidb/v5.4/system-variables/#version

在5.1的时候,version字段是5.7.25-TiDB-(tidb version),也就是tidb会被驱动识别为5.7.25版本的mysql。

https://docs.pingcap.com/zh/tidb/v7.5/system-variables/#version

在7.5的时候,version字段是 8.0.11-TiDB-(tidb version),也就是驱动识别tidb为mysql 8.0.11。

我怀疑是这个地方让驱动识别的mysql版本发生了变化,然后就导致了你现在的问题。
你尝试使用新的mysql驱动也没解决,是因为新驱动识别出来的msyql版本还是8.0.11。

我感觉你可以把这个地方改回5.7.25-TiDB-(tidb version)这种格式。看看问题是否已经解决。

https://docs.pingcap.com/zh/tidb/v7.5/system-variables/#version
version

  • 作用域:NONE
  • 是否受 Hint SET_VAR 控制:否
  • 默认值:8.0.11-TiDB-(tidb version)
  • 这个变量的值是 MySQL 的版本和 TiDB 的版本,例如 ‘8.0.11-TiDB-v7.5.6’。

==
version 好象是一个只读参数,无法修改。

需要修改 config:https://docs.pingcap.com/zh/tidb/stable/tidb-configuration-file/#server-version
配置是这个。

1 个赞

多谢,这种select version()是版本变了。

select version();
±-------------------+
| version() |
±-------------------+
| 5.7.25-TiDB-v5.1.4 |
±-------------------+
1 row in set (0.00 sec)

配置:
server_configs:
tidb:
binlog.enable: false
server-version: 5.7.25-TiDB-v5.1.4

改了之后问题解决了?

1)有类似事件

2)研发改代码解决的。
Map<String, Object> item = Maps.newHashMap();
for(Map.Entry<String,Object> entry: item1.entrySet()){
String key = entry.getKey();
Object value = entry.getValue();
if (value != null && value instanceof byte){
value = new String((byte) value, StandardCharsets.UTF_8);
}
item.put(key,value);
}

1 个赞