已知的第三方工具兼容问题

本文列举的兼容性问题是在一些 TiDB 支持的第三方工具中发现的。

通用

TiDB 中 SELECT CONNECTION_ID() 返回结果类型为 64 位整型

描述

TiDB 中 SELECT CONNECTION_ID() 的返回值为 64 位,如 2199023260887。而 MySQL 中返回值为 32 位,如 391650

规避方法

在 TiDB 应用程序中,请注意使用各语言的 64 位整型类型(或字符串类型)存储 SELECT CONNECTION_ID() 的结果,防止溢出。如 Java 应使用 LongString 进行接收,JavaScript/TypeScript 应使用 string 类型进行接收。

TiDB 未设置 Com_* 计数器

描述

MySQL 维护了一系列 Com_ 开头的服务端变量来记录你对数据库的操作总数,如 Com_select 记录了 MySQL 数据库从上次启动开始,总共发起的 SELECT 语句数(即使语句并未成功执行)。而 TiDB 并未维护此变量。你可以使用语句 SHOW GLOBAL STATUS LIKE 'Com_%' 观察 TiDB 与 MySQL 的差异。

规避方法

请勿使用这样的变量。在 MySQL 中 Com_* 常见的使用场景之一是监控。TiDB 的可观测性较为完善,无需从服务端变量进行查询。如需定制监控工具,可阅读 TiDB 监控框架概述来获得更多信息。

TiDB 错误日志区分 TIMESTAMPDATETIME 类型

描述

TiDB 错误日志区分 TIMESTAMPDATETIME,而 MySQL 不区分,全部返回为 DATETIME。即 MySQL 会将 TIMESTAMP 类型的报错信息错误地写为 DATETIME 类型。

规避方法

请勿使用错误日志进行字符串匹配,要使用错误码进行故障诊断。

TiDB 不支持 CHECK TABLE 语句

描述

TiDB 不支持 CHECK TABLE 语句。

规避方法

在 TiDB 中使用 ADMIN CHECK [TABLE|INDEX] 语句进行表中数据和对应索引的一致性校验。

与 MySQL JDBC 的兼容性

测试版本为 MySQL Connector/J 8.0.29。

默认排序规则不一致

描述

MySQL Connector/J 的排序规则保存在客户端内,通过获取的服务端版本进行判别。

下表列出了已知的客户端与服务端排序规则不一致的字符集:

字符集客户端默认排序规则服务端默认排序规则
asciiascii_general_ciascii_bin
latin1latin1_swedish_cilatin1_bin
utf8mb4utf8mb4_0900_ai_ciutf8mb4_bin

规避方法

在 TiDB 中手动设置排序规则,不要依赖客户端默认排序规则。客户端默认排序规则由 MySQL Connector/J 配置文件保存。

参数 NO_BACKSLASH_ESCAPES 不生效

描述

TiDB 中无法使用 NO_BACKSLASH_ESCAPES 参数从而不进行 \ 字符的转义。已提 issue

规避方法

在 TiDB 中不搭配使用 NO_BACKSLASH_ESCAPES\,而是使用 \\ 编写 SQL 语句。

未设置索引使用情况参数

描述

TiDB 在通讯协议中未设置 SERVER_QUERY_NO_GOOD_INDEX_USEDSERVER_QUERY_NO_INDEX_USED 参数。这将导致以下参数返回与实际不一致:

  • com.mysql.cj.protocol.ServerSession.noIndexUsed()
  • com.mysql.cj.protocol.ServerSession.noGoodIndexUsed()

规避方法

不使用 noIndexUsed()noGoodIndexUsed() 函数。

不支持 enablePacketDebug 参数

描述

TiDB 不支持 enablePacketDebug 参数,这是一个 MySQL Connector/J 用于调试的参数,将保留数据包的 Buffer。这将导致连接的意外关闭请勿打开。

规避方法

不设置 enablePacketDebug 参数。

不支持 UpdatableResultSet

描述

TiDB 暂不支持 UpdatableResultSet,即请勿指定 ResultSet.CONCUR_UPDATABLE 参数,也不要在 ResultSet 内部进行数据更新。

规避方法

使用 UPDATE 语句进行数据更新,可使用事务保证数据一致性。

MySQL JDBC Bug

useLocalTransactionStaterewriteBatchedStatements 同时开启将导致事务无法提交或回滚

描述

useLocalTransactionStaterewriteBatchedStatements 两参数同时开启时,将导致事务无法提交。你可以使用代码复现。

规避方法

请勿开启 useLocalTransactionState,这有可能导致事务无法提交或回滚。

Connector 无法兼容 5.7.5 版本以下的服务端

描述

MySQL Connector/J 8.0.29 在与 5.7.5 版本以下的 MySQL 服务端,或使用 5.7.5 版本以下 MySQL 服务端协议的数据库(如 TiDB 6.3.0 版本以下)同时使用时,将在某些情况下导致数据库连接的挂起。关于更多细节信息,可查看此 Bug Report

规避方法

这是一个已知的问题,截至 2022 年 10 月 12 日,MySQL Connector/J 未合并修复代码。

TiDB 对其进行了两个维度的修复:

  • 客户端方面:pingcap/mysql-connector-j 中修复了该 Bug,你可以使用 pingcap/mysql-connector-j 替换官方的 MySQL Connector/J。
  • 服务端方面:TiDB v6.3.0 修复了此兼容性问题,你可以升级服务端至 v6.3.0 或以上版本。

与 Sequelize 的兼容性

本小节描述的兼容性信息基于 Sequelize v6.32.1 测试。

根据测试结果,TiDB 支持绝大部分 Sequelize 功能(使用 MySQL 作为方言),不支持的功能有:

  • 不支持 GEOMETRY 相关。
  • 不支持修改整数主键。
  • 不支持 PROCEDURE 相关。
  • 不支持 READ-UNCOMMITTEDSERIALIZABLE 隔离级别
  • 默认不允许修改列的 AUTO_INCREMENT 属性。
  • 不支持 FULLTEXTHASHSPATIAL 索引。
  • 不支持 sequelize.queryInterface.showIndex(Model.tableName);
  • 不支持 sequelize.options.databaseVersion
  • 不支持使用 queryInterface.addColumn 添加外键引用。

不支持修改整数主键

描述

不支持修改整数类型的主键,这是由于当主键为整数类型时,TiDB 使用其作为数据组织的索引。你可以在此 Issue聚簇索引一节中获取更多信息。

不支持 READ-UNCOMMITTEDSERIALIZABLE 隔离级别

描述

TiDB 不支持 READ-UNCOMMITTEDSERIALIZABLE 隔离级别。设置事务隔离级别为 READ-UNCOMMITTEDSERIALIZABLE 时将报错。

规避方法

仅使用 TiDB 支持的 REPEATABLE-READREAD-COMMITTED 隔离级别。

如果你的目的是兼容其他设置 SERIALIZABLE 隔离级别的应用,但不依赖于 SERIALIZABLE,你可以设置 tidb_skip_isolation_level_check1,此后如果对 tx_isolationtransaction_isolation 别名)赋值一个 TiDB 不支持的隔离级别(READ-UNCOMMITTEDSERIALIZABLE),不会报错。

默认不允许修改列的 AUTO_INCREMENT 属性

描述

默认不允许通过 ALTER TABLE MODIFYALTER TABLE CHANGE 来增加或移除某个列的 AUTO_INCREMENT 属性。

规避方法

参考 AUTO_INCREMENT 的使用限制

设置 @@tidb_allow_remove_auto_inctrue,即可允许移除 AUTO_INCREMENT 属性。

不支持 FULLTEXTHASHSPATIAL 索引

描述

TiDB 不支持 FULLTEXTHASHSPATIAL 索引。