乐趣区

关于tidb:TiDB-60-新特性解读丨-Collation-规则

对数据库而言,适合的字符集和规定可能大大晋升使用者运维和剖析的效率。TiDB 从 v4.0 开始反对新 collation 规定,并于 TiDB 6.0 版本进行了更新。本文将深刻解读 Collation 规定在 TiDB 6.0 中的变更和利用。

Ps. 本文已入选 TiDB 6.0 Book Rush,如果你也想分享 6.0 的应用体验,并取得丰富处分,欢送退出咱们!

这里的“引”,有两层含意,这第一层是“ 言”,从 TiDB v6.0 发版阐明 中能够理解到,TiDB 6.0 引入了很多新个性,同时也引入了新的 发版模型,本文将对 TiDB 6.0 新个性一睹为快。

第二层含意是“抛砖 玉”,开源社区的力量是无穷尽的,心愿有更多人能够参加到开源中来,那么如何参加开源,其实路径远不止提交代码一种,比方,在 AskTUG 社区发问、答复、互动,再如,发现 TiDB 官网文档 有 Bug 或信息不残缺,提出 Issue 和解决方案,又如,参加 TiDB 6.0 Book Rush! 流动,做版本评测、案例文章等等。

默认启用新 Collation 规定

TiDB 从 v4.0 开始反对新 collation 规定,在大小写不敏感、口音不敏感、padding 规定上与 MySQL 行为保持一致。

TiDB 6.0 引入了新的 Collation 规定,并将默认启用新 Collation 框架。新 Collation 规定已在 TiDB 4.0 引入,但始终都是默认敞开项,只有集群初始化时能力变更。可通过零碎表看到该变量值的设定。

TiDB [(none)] 18:45:27> select * from mysql.tidb where variable_name = 'new_collation_enabled';
+-----------------------+----------------+----------------------------------------------------+
| VARIABLE_NAME         | VARIABLE_VALUE | COMMENT                                            |
+-----------------------+----------------+----------------------------------------------------+
| new_collation_enabled | True           | If the new collations are enabled. Do not edit it. |
+-----------------------+----------------+----------------------------------------------------+
1 row in set (0.003 sec)

查看 I\_S.collations 表,能够晓得 TiDB 6.0 已反对 11 种规定,较之前未启用新 collation 框架的版本新增了 5 种规定,别离是 gbk_bin, gbk_chinese_ci, utf8_general_ciutf8_unicode_ci, utf8mb4_unicode_ci

因为很多旧零碎应用的是 GBK 字符集,所以在做零碎重构的我的项目,尤其波及到数据迁徙的状况时,对于 GBK 字符集的反对就显得尤为重要和实用。当然,对于新我的项目,倡议应用 UTF8mb4。

TiDB [(none)] 18:45:51> select version()\G
*************************** 1. row ***************************
version(): 5.7.25-TiDB-v6.0.0
1 row in set (0.001 sec)

TiDB [(none)] 18:46:00> SELECT * FROM information_schema.collations;
+--------------------+--------------------+------+------------+-------------+---------+
| COLLATION_NAME     | CHARACTER_SET_NAME | ID   | IS_DEFAULT | IS_COMPILED | SORTLEN |
+--------------------+--------------------+------+------------+-------------+---------+
| ascii_bin          | ascii              |   65 | Yes        | Yes         |       1 |
| binary             | binary             |   63 | Yes        | Yes         |       1 |
| gbk_bin            | gbk                |   87 |            | Yes         |       1 | (#28645)
| gbk_chinese_ci     | gbk                |   28 | Yes        | Yes         |       1 | (#28645)
| latin1_bin         | latin1             |   47 | Yes        | Yes         |       1 |
| utf8_bin           | utf8               |   83 | Yes        | Yes         |       1 |
| utf8_general_ci    | utf8               |   33 |            | Yes         |       1 |
| utf8_unicode_ci    | utf8               |  192 |            | Yes         |       1 | (#18678)
| utf8mb4_bin        | utf8mb4            |   46 | Yes        | Yes         |       1 |
| utf8mb4_general_ci | utf8mb4            |   45 |            | Yes         |       1 |
| utf8mb4_unicode_ci | utf8mb4            |  224 |            | Yes         |       1 | (#18678)
+--------------------+--------------------+------+------------+-------------+---------+
11 rows in set (0.001 sec)

TiDB [test] 19:05:14> SHOW CHARACTER SET;
+---------+-------------------------------------+-------------------+--------+
| Charset | Description                         | Default collation | Maxlen |
+---------+-------------------------------------+-------------------+--------+
| ascii   | US ASCII                            | ascii_bin         |      1 |
| binary  | binary                              | binary            |      1 |
| gbk     | Chinese Internal Code Specification | gbk_chinese_ci    |      2 |
| latin1  | Latin1                              | latin1_bin        |      1 |
| utf8    | UTF-8 Unicode                       | utf8_bin          |      3 |
| utf8mb4 | UTF-8 Unicode                       | utf8mb4_bin       |      4 |
+---------+-------------------------------------+-------------------+--------+
6 rows in set (0.001 sec)

而在 TiDB v5.4 未启用新 Collation 的后果为:

TiDB-v5.4 [test] 10:17:22> select version()\G
*************************** 1. row ***************************
version(): 5.7.25-TiDB-v5.4.0
1 row in set (0.001 sec)

TiDB-v5.4 [test] 10:19:39> SELECT * FROM information_schema.collations;
+----------------+--------------------+------+------------+-------------+---------+
| COLLATION_NAME | CHARACTER_SET_NAME | ID   | IS_DEFAULT | IS_COMPILED | SORTLEN |
+----------------+--------------------+------+------------+-------------+---------+
| utf8mb4_bin    | utf8mb4            |   46 | Yes        | Yes         |       1 |
| latin1_bin     | latin1             |   47 | Yes        | Yes         |       1 |
| binary         | binary             |   63 | Yes        | Yes         |       1 |
| ascii_bin      | ascii              |   65 | Yes        | Yes         |       1 |
| utf8_bin       | utf8               |   83 | Yes        | Yes         |       1 |
| gbk_bin        | gbk                |   87 | Yes        | Yes         |       1 |
+----------------+--------------------+------+------------+-------------+---------+
6 rows in set (0.001 sec)

新 Collation 注意事项

对于 TiDB 6.0 之前的版本,该配置项的默认值始终为 false,但能够在集群初始化之前就扭转其设定,如此就能够在集群初始化之后应用新的 collation 框架。

service_configs:
  tidb:
    new_collations_enabled_on_first_bootstrap: true

不过,这里要强调留神的是,当 TiDB 集群跨大版本升级时,须要查看配置项。免得呈现上下游集群字符校验规定不统一而导致数据不同步或查问后果不统一的状况。另外,当应用 BR 进行数据备份、复原时,也须要留神 Collation 的设置,保障备份前、复原后的集群设置雷同,防止出现因配置项new_collations_enabled_on_first_bootstrap 设定不同而报错。

Collation Bug 修复

TiDB 6.0 中修复了 2 个对于 Collation 的 Bug,别离与比拟函数和 JSON 相干,上面举两个小案例对其进行测试。

1. 修复带有 collation 的 greatest 或 least 函数后果出错的问题 #31789

测试用例:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 char(20) CHARACTER SET utf8 COLLATE utf8_bin,
c2 char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin);
INSERT INTO t1 VALUES ('UUtJeaV','snRXXCZHBPW');

SET names utf8mb4 collate utf8mb4_bin;
SELECT greatest(c1, c2) as expr1 FROM t1;
SELECT least(c1, c2) as expr1 FROM t1;

SET names utf8mb4 collate utf8mb4_general_ci;
SELECT greatest(c1, c2) as expr1 FROM t1;
SELECT least(c1, c2) as expr1 FROM t1;

测试后果:

2. 修复了 json 类型在 builtin-func 中推导 collation 谬误的问题 #31320

修复这个问题的次要代码如下,冀望体现是与 MySQL 统一,在应用 JSON 类型的外部办法时,该当始终应用 utf8mb4\_bin 规定。

// The collation of JSON is always utf8mb4_bin in builtin-func which is same as MySQL
// see details https://github.com/pingcap/tidb/issues/31320#issuecomment-1010599311
if isJSON {dstCharset, dstCollation = charset.CharsetUTF8MB4, charset.CollationUTF8MB4}

测试用例:

DROP TABLE IF EXISTS t2;
CREATE TABLE t2 (c1 json);
INSERT INTO t2 VALUES ('{\" 测试 \": \" 你好 \"}');

SELECT collation(c1), collation(upper(c1)), collation(elt(1, c1, 0x12)) FROM t2;

测试后果:

在 TiDB v5.4 中的测试后果为:

新增内置函数 CHARSET()

TiDB 6.0 新增了一个新内置函数,用来断定入参的字符集,这与 Collation 是相关联的,所以一并举例演示。注:从 Issue #3931 记录来看,这个需要早在 2017 年就提出来了,然而到 6.0 才合并到骨干代码。

TiDB [test] 23:54:42> select version()\G
*************************** 1. row ***************************
version(): 5.7.25-TiDB-v6.0.0
1 row in set (0.001 sec)

TiDB [test] 00:03:51> set names utf8mb4;
Query OK, 0 rows affected (0.000 sec)

TiDB [test] 00:03:58> select charset(1);
+------------+
| charset(1) |
+------------+
| binary     |
+------------+
1 row in set (0.001 sec)

TiDB [test] 00:04:03> select charset('1');
+--------------+
| charset('1') |
+--------------+
| utf8mb4      |
+--------------+
1 row in set (0.001 sec)

文档拾遗

正如开篇所提到的,参加开源的路径有很多种,咱们从开源中收益,天然也要回馈社区。

举一个理论例子,在写本文查阅文档时,就发现了 Collations 这节在 v6.0 (DMR) 版本下的查问后果集与理论不符,于是便进行了反馈。

在 GitHub 上提交了 Issue,处理速度也很快,第二天就曾经实现初步批改,现处于期待 Merge 到 master 的状态。

相干 Issue 链接为:https://github.com/pingcap/do…

本文对 Collation 个性在 TiDB 6.0 中的变更进行了汇总阐释及举例说明,以后 TiDB 所提供的几种 Collation 曾经能够撑持大部分业务场景和大部分零碎迁徙需要。倡议在我的项目设计之初,就选用普适类型的字符集和规定,毕竟效率是晋升生产力的重要因素之一。

流动预报

新公布的 TiDB 6.0 大幅加强了 TiDB 作为企业级产品的可管理性,具备更成熟的 HTAP 与容灾能力,退出多项云原生数据库所需的根底个性。领先试用 TiDB 6.0、TiFlash、TiEM 和 PingCAP Clinic 等多款新品与服务,参加 Book Rush 奉献,将有机会享受“TiDB 荣誉体验官”在内的多项权利!

退出移动版