字符集转换

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【 TiDB 使用环境】
tidb支持 utf8 转utf8mb4,但不支持逆转,有什么考虑吗

【概述】 场景 + 问题概述

【应用框架及开发适配业务逻辑】

【背景】 做过哪些操作

【现象】 业务和数据库现象

【问题】 当前遇到的问题

【业务影响】

【TiDB 版本】

【附件】 相关日志及监控(https://metricstool.pingcap.com/)


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

1 个赞

你运气真好,新手小菜鸟正在学这个,第一次回答问题,看来离版主进了一步。

TiDB 目前支持以下字符集:

tidb> SHOW CHARACTER SET;
+---------|---------------|-------------------|--------+
| Charset | Description   | Default collation | Maxlen |
+---------|---------------|-------------------|--------+
| utf8    | UTF-8 Unicode | utf8_bin          |      3 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_bin       |      4 |
| ascii   | US ASCII      | ascii_bin         |      1 |
| latin1  | Latin1        | latin1_bin        |      1 |
| binary  | binary        | binary            |      1 |
+---------|---------------|-------------------|--------+
5 rows in set (0.00 sec)

注意:TiDB 的默认字符集为 utf8mb4 ,MySQL 5.7 中为 latin1 ,MySQL 8.0 中修改为 utf8mb4 。 当指定的字符集为 utf8utf8mb4 时,TiDB 仅支持合法的 UTF8 字符。对于不合法的字符,会报错: incorrect utf8 value ,该字符合法性检查与 MySQL 8.0 一致。对于 MySQL 5.7 及以下版本,会存在允许插入非法 UTF8 字符,但同步到 TiDB 报错的情况。此时,可以通过 TiDB 配置 “tidb_skip_utf8_check” 跳过 UTF8 字符合法性检查强制写入 TiDB。

每一个字符集,都有一个默认的 Collation,例如 utf8 的默认 Collation 为 utf8_bin ,TiDB 中字符集的默认 Collation 与 MySQL 不一致,具体如下:

字符集 TiDB 默认 Collation MySQL 5.7 默认 Collation MySQL 8.0 默认 Collation
utf8 utf8_bin utf8_general_ci utf8_general_ci
utf8mb4 utf8mb4_bin utf8mb4_general_ci utf8mb4_0900_ai_ci
ascii ascii_bin ascii_general_ci ascii_general_ci
latin1 latin1_bin latin1_swedish_ci latin1_swedish_ci
binary binary binary binary

在 4.0 版本之前,TiDB 中可以任意指定字符集对应的所有 Collation,并把它们按照默认 Collation 处理,即以编码字节序为字符定序。同时,并未像 MySQL 一样,在比较前按照 Collation 的 PADDING 属性将字符补齐空格。因此,会造成以下的行为区别:

tidb> create table t(a varchar(20) charset utf8mb4 collate utf8mb4_general_ci primary key);
Query OK, 0 rows affected
tidb> insert into t values ('A');
Query OK, 1 row affected
tidb> insert into t values ('a');
Query OK, 1 row affected // MySQL 中,由于 utf8mb4_general_ci 大小写不敏感,报错 Duplicate entry 'a'.
tidb> insert into t1 values ('a ');
Query OK, 1 row affected // MySQL 中,由于补齐空格比较,报错 Duplicate entry 'a '

TiDB 4.0 新增了完整的 Collation 支持框架,允许实现所有 MySQL 中的 Collation,并新增了配置开关 new_collation_enabled_on_first_boostrap ,在集群初次初始化时决定是否启用新 Collation 框架。在该配置开关打开之后初始化集群,可以通过 mysql . tidb 表中的 new_collation_enabled 变量确认新 Collation 是否启用:

tidb> select VARIABLE_VALUE from mysql.tidb where VARIABLE_NAME='new_collation_enabled';
+----------------+
| VARIABLE_VALUE |
+----------------+
| True           |
+----------------+
1 row in set (0.00 sec)

在新 Collation 启用后,TiDB 修正了 utf8mb4_general_binutf8_general_binPADDING 行为,会将字符串补齐空格后比较;同时支持了 utf8mb4_general_ciutf8_general_ci ,这两个 Collation 与 MySQL 保持兼容。

恰巧一个需求把utf8mb4转utf8,又恰巧只有tidb 环境

1 个赞

昨天刚刚tiup playgroud v5.0.0 --db 2 --pd 3 --kv 3 --monitor 单机启动的环境

mysql确实是可以,不过tidb不支持。可能因为utf8mb4是utf8的超集,utf8mb4改utf8可能会导致一些现有的数据有问题,而且几乎不会有utf8mb4改成utf8的需求,我想不到什么场景需要这样做。生产环境建议还是统一utf8mb4吧。

2 个赞

我也是这么给开发讲的

我目前遇到一个问题,Ticdc做增量迁移时,上游tidb,下游mysql5.0,导致无法识别utf8mb4,请问这种情况该如何处理

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