黄东旭解析 TiDB 的核心优势
580
2024-03-18
本文将延续本系列文章,介绍如何编译 TiDB Server 源码。以及,阐释 TiDB Server 7.x 的部分新特性。
News !!!
TiDB v7.5.0 LTS 计划于 2023-11-23 正式 Release[1],目前代码虽未冻结,但已经可以看到 Alpha 版本的 Code 了,本文代码将以 v7.5.0-alpha 为基准。
本文是该系列文章的第 5 篇,前四篇文章分别是:
TiDB 7.x 源码编译之 PD/TiDB Dashboard 篇
TiDB 7.x 源码编译之 TiUP 篇,及新特性解析
TiDB 7.x 源码编译之 TiFlash 篇
TiDB 7.x 源码编译之 TiProxy 篇,及尝鲜体验
与前几篇文章有所区别的是,本文使用 CentOS 7.9 和 Rocky Linux 9.2 两个版本的操作系统,分别进行编译测试。由于 TiDB Server 是 go 语言开发,所以在两个系统编译过程几乎没有区别,只需注意在编译之前安装系统开发工具包(yum groupinstall Development Tools)。不过,官档[2]中并未明确支持 Rocky Linux 系统,所以,如需在生产环境使用,请慎重评审。
查看版本信息:
cat /etc/redhat-release uname -a输出日志:
CentOS 7
[shawnyan@centos7 ~]$ cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [shawnyan@centos7 ~]$ uname -a Linux centos7.shawnyan.cn 3.10.0-1160.92.1.el7.x86_64 #1 SMP Tue Jun 20 11:48:01 UTC 2023 x86_64 x86_64 x86_64 GNU/LinuxRocky Linux 9
[root@rocky9 ~]# cat /etc/redhat-release Rocky Linux release 9.2 (Blue Onyx) [root@rocky9 ~]# uname -a Linux rocky9.shawnyan.cn 5.14.0-284.11.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Tue May 9 17:09:15 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux在 TiDB v7.5.0-alpha 的代码中,Go 版本升级到 1.21.1 (released 2023-08-08)[3][4]。本文所使用的 Go 版本为 1.21.3 (released 2023-10-10)[5]。
go install golang.org/dl/go1.21.3@latest go1.21.3 download go1.21.3 versiongo version go1.21.3 linux/amd64Ps. 同时,关于 Go 版本,给 QE 团队提了个 Issue:[Closed] update go v1.21.3 #2507
Update: 2023-10-17
TiDB 源码仓库新建了 release-7.5分支,并且 Go 版本升级到了 1.21.3。[6]
克隆下载源码到本地,这里指定 v7.5.0-alpha 分支。
$ git clone https://github.com/pingcap/tidb.git --depth=1 -b v7.5.0-alpha tidb7 $ cd tidb7 $ git lg * 8cfe7f3 - (grafted, HEAD -> v7.5.0-alpha, tag: v7.5.0-alpha) executor, tests: move some test cases from `admin_test.go` and `foreign_key_test.go` to `integrationtest` (#47333) (12 days ago) <SeaRise>编译 TiDB Server 仅需一条命令搞定。
make输出日志:
[shawnyan@centos7 tidb7]$ make CGO_ENABLED=1 GO111MODULE=on go build -tags codes -ldflags -X "github.com/pingcap/tidb/parser/mysql.TiDBReleaseVersion=v7.5.0-alpha" -X "github.com/pingcap/tidb/util/versioninfo.TiDBBuildTS=2023-10-11 06:08:32" -X "github.com/pingcap/tidb/util/versioninfo.TiDBGitHash=8cfe7f329b56899a96422596da2b67d4e2bd1e94" -X "github.com/pingcap/tidb/util/versioninfo.TiDBGitBranch=HEAD" -X "github.com/pingcap/tidb/util/versioninfo.TiDBEdition=Community" -o bin/tidb-server ./tidb-server Build TiDB Server successfully!查看二进制文件的版本:
[shawnyan@centos7 bin]$ ./tidb-server -V Release Version: v7.5.0-alpha Edition: Community Git Commit Hash: 8cfe7f329b56899a96422596da2b67d4e2bd1e94 Git Branch: HEAD UTC Build Time: 2023-10-11 06:08:32 GoVersion: go1.21.3 Race Enabled: false Check Table Before Drop: false Store: unistoreUpdate: 2023-10-16
TiDB 仓库的代码结构发生了大调整,TiDB Server 核心文件移动到了新目录 pkg[7],这一变更影响到近 4500 个文件。随之而来的好处是,TiDB 源码根目录更加清晰。
[shawnyan@centos7 tidb7]$ tree . -L 1 . ├── br --> BR ├── build ... ├── cmd ... ├── docs ├── dumpling --> Dumpling ... ├── pkg --> TiDB core ... ├── tests ├── tools ... 10 directories, 24 filesTiDB Server 其实可以不依赖于 TiKV 而单独启动,这里选择单机存储引擎 UniStore 启动 TiDB Server,启动命令如下。
./tidb-server -store unistore启动后,连接 TiDB,并查看版本信息。
tidb> select tidb_version()\G *************************** 1. row *************************** tidb_version(): Release Version: v7.5.0-alpha Edition: Community Git Commit Hash: 8cfe7f329b56899a96422596da2b67d4e2bd1e94 Git Branch: HEAD UTC Build Time: 2023-10-11 06:08:32 GoVersion: go1.21.3 Race Enabled: false Check Table Before Drop: false Store: unistore 1 row in set (0.00 sec)需要注意的是,TiDB Server 的参数分为命令行参数(直接启动 Server 时传递的参数)[8],配置文件参数(比命令行参数更丰富)[9],以及系统变量(连接 TiDB 后可修改)[10],所以在查看官方文档的时候,这三类参数的页面都可能用到,概念上的变量和参数非常容易混淆,如果接触 TiDB 时间不长,需要多加区分、辨别。
BTW,关于这部分的内容,欢迎学习、复习 PingCAP 相关课程:
TiDB 系统管理基础 [TiDB v5.x] (301) ,第十课: TiDB 的配置
到此,我们可以看到 TiDB Server 已经编译成功,并成功启动运行,TiDB Server 的版本为 v7.5.0-alpha。
依据现行 TiDB 发版规则,TiDB 7.5.0 LTS 版本将包含 7.2.0-DMR (Released: 2023-06-29),7.3.0-DMR (Released: 2023-08-14) 和 7.4.0-DMR (Released: 2023-10-12) 中已发布的新特性。 下面的篇幅将介绍若干 TiDB 7.x 的新特性。
在 TiDB 7.1.0 LTS 中,资源管控特性正式发布,这部分的详细内容请参考文章:
《 TiDB 7.1.0 LTS 特性解读丨关于资源管控 (Resource Control) 应该知道的 6 件事 》
在 TiDB 7.4.0 DMR 中,资源管控能力得到增强,引入了对后台任务的管理。主要实现在 TiKV 层。
当一种任务被标记为后台任务时,TiKV 会动态地限制该任务的资源使用,以尽量避免此类任务在执行时对其他前台任务的性能产生影响。TiKV 通过实时地监测所有前台任务所消耗的 CPU 和 IO 等资源,并根据实例总的资源上限计算出后台任务可使用的资源阈值,所有后台任务在执行时会受此阈值的限制。
同时,在 v7.4.0 中,TiFlash 支持资源管控特性,完善了 TiDB 整体的资源管控能力。#7660
之前的文章 《 TiDB 7.1.0 LTS 特性解读 | 资源管控 (Resource Control) 应该知道的 6 件事 》 中,增加了“资源管控”相关 SQL,这里再次进行扩展,也是本文的第一个彩蛋。
从 TiDB v7.1.0 开始,支持Optimizer Fix Controls 特性,并引入 tidb_opt_fix_control 系统变量,以更细粒度控制优化器行为。
现在,该变量支持全局、会话、Hint,三种方式进行控制,正式发布支持的控制项有 6 个,另有 1 个已合入 Master,预计会随下个版本发布,具体列表如下。
44262 – New in v7.2.0/v7.1.1
控制是否允许使用动态模式访问没有全局统计信息的分区表。
44389 – New in v7.2.0/v7.1.1
控制在构建范围时是否考虑某些 CNF 项的非点范围(non-point ranges)。
44823– New in v7.3.0/v7.1.1
控制可以在计划缓存中缓存的查询参数的最大数量。
44830 – New in v7.3.0
控制是否允许缓存某些复杂场景中的 Batch/PointGet。
44855 – New in v7.3.0/v7.1.1
控制在估计索引连接内侧下索引范围扫描的行数时是否使用更准确的上限。
45132 – New in v7.4.0
控制是否使用访问范围行计数来确定 Skyline 修剪上的访问路径。
45798
控制是否缓存访问生成列的计划。
基础用法示例如下:
SET @@tidb_opt_fix_control=default; select @@tidb_opt_fix_control; SET SESSION tidb_opt_fix_control = 44262:ON,44389:ON,44823:500,44830:ON,44855:ON,45132:0,45798:ON; SET GLOBAL tidb_opt_fix_control = ; select /*+ set_var(tidb_opt_fix_control="1:ok") */ @@tidb_opt_fix_control;TiDB 7.2 引入了新的实验特性,DDL 任务支持暂停(PAUSE)[11]和恢复(RESUME)操作,比如,对正在创建索引的任务进行暂停和恢复。相关命令如下:
ADMIN PAUSE DDL JOBS job_id [, job_id] ADMIN RESUME DDL JOBS job_id [, job_id]t从 TiDB 7.3.0 开始,新增支持 8 (4+1+3) 项表级别 Optimizer Hint,这一特性也在 TiDB v7.1.1 中引入。
“4+1+3” 的意思是,增加 4 个名为 NO_xxx_JOIN 的 TiDB Hint,兼容(MySQL)一个名为 NO_HASH_JOIN[12] 的 Hint,以及,增加 3 个名为 INDEX_xxx_JOIN 的 TiDB Hint,具体名称如下。
NO_INDEX_JOIN NO_INDEX_HASH_JOIN NO_INDEX_MERGE_JOIN NO_MERGE_JOIN NO_HASH_JOIN INDEX_JOIN INDEX_HASH_JOIN INDEX_MERGE_JOIN此外,在使用 Hint 时,如果 INDEX_xxx_JOIN 与 NO_INDEX_xxx_JOIN 发生冲突,NO_INDEX_xxx_JOIN 可能会被忽略。
另外一个知识点,在 TiDB 中,TIDB_INLJ 是 INL_JOIN 的别名。
在 3.0.x 及之前版本仅支持使用该别名;之后的版本同时支持使用这两种名称,但推荐使用 INL_JOIN。[13]
// TiDB hint aliases "TIDB_HJ": hintHashJoin, -> HASH_JOIN "TIDB_INLJ": hintInlJoin, -> INL_JOIN "TIDB_SMJ": hintSMJoin, -> MERGE_JOIN在使用方法上,还可以结合 SEV_VAR Hint 使用,本文下面有章节会再介绍。
示例:
explain format = hint SELECT /*+ NO_INDEX_JOIN(t1),NO_INDEX_HASH_JOIN(t1),NO_INDEX_MERGE_JOIN(t1),NO_MERGE_JOIN(t1) ,NO_HASH_JOIN(t1),INDEX_JOIN(t1),INDEX_HASH_JOIN(t1),INDEX_MERGE_JOIN(t1) */ * FROM t1\G输出:
mysql> explain format = hint SELECT /*+ NO_INDEX_JOIN(t1),NO_INDEX_HASH_JOIN(t1),NO_INDEX_MERGE_JOIN(t1),NO_MERGE_JOIN(t1) ,NO_HASH_JOIN(t1),INDEX_JOIN(t1),INDEX_HASH_JOIN(t1),INDEX_MERGE_JOIN(t1) */ * FROM t1\G *************************** 1. row *************************** hint: use_index(@`sel_1` `test`.`t1` `idx_t1`), no_order_index(@`sel_1` `test`.`t1` `idx_t1`), no_index_join(), no_index_hash_join(), no_index_merge_join(), no_merge_join(), no_hash_join(), index_join(), index_hash_join(), index_merge_join() 1 row in set (0.00 sec)相关 PR 参见:parser: support more join hints on parser #45525
具体相关文档参见:Optimizer Hints
Ps. 文档有部分描述缺失,已提 Issue,期待更新。
[Open] docs: add description about optimizer hint #15358
iDB 7.4.0,新增支持TIDB_PARSE_TSO_LOGICAL() 语法
对于 TSO,如果想查看逻辑计数器,之前的版本需要通过 pd 命令进行解析,从 7.4 开始支持直接从 TiDB 进行查询。
TSO 指 Time Stamp ***,是 PD (Placement Driver) 为每个事务提供的单调递增的时间戳。TSO 是一串数字,包含以下两部分:一个物理时间戳; 一个逻辑计数器[12]
示例:获取物理时间戳和逻辑计数器的值。
tidb> select @@tidb_current_ts; +--------------------+ | @@tidb_current_ts | +--------------------+ | 444995429049565185 | +--------------------+ 1 row in set (0.00 sec) tidb> SELECT TIDB_PARSE_TSO(@@tidb_current_ts); +-----------------------------------+ | TIDB_PARSE_TSO(@@tidb_current_ts) | +-----------------------------------+ | 2023-10-17 15:07:26.411000 | +-----------------------------------+ 1 row in set (0.00 sec) tidb> SELECT TIDB_PARSE_TSO_LOGICAL(@@tidb_current_ts); +-------------------------------------------+ | TIDB_PARSE_TSO_LOGICAL(@@tidb_current_ts) | +-------------------------------------------+ | 1 | +-------------------------------------------+ 1 row in set (0.00 sec)与 pd 命令解析的结果一致。
tidb> \! tiup ctl:v7.4.0 pd tso 444995429049565185 The component `ctl` version v7.4.0 is not installed; downloading from repository. Starting component `ctl`: /home/shawnyan/.tiup/components/ctl/v7.4.0/ctl pd tso 444995429049565185 system: 2023-10-17 15:07:26.411 +0800 CST logic: 1 tidb>TiDB 7.4 的分区表管理功能更加完备,期待已久的普通表转分区表功能终于上线。[13]
-- 将非分区表转为分区表、修改分区表的分区类型 ALTER TABLE <table_name> PARTITION BY <new partition type and definitions> -- 将分区表转为非分区表 ALTER TABLE <table_name> REMOVE PARTITIONING举个栗子,将既存表按年龄划定分区,分区类型使用 RANGE,然后将分区类型变更为 LIST,最后移除分区。
tidb> show create table t_age\G *************************** 1. row *************************** Table: t_age Create Table: CREATE TABLE `t_age` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin 1 row in set (0.00 sec) -- 转为分区表 tidb> ALTER TABLE t_age PARTITION BY RANGE (a) -> ( PARTITION p0 VALUES LESS THAN (18) -> , PARTITION p1 VALUES LESS THAN (35) -> , PARTITION p2 VALUES LESS THAN (MAXVALUE)); Query OK, 0 rows affected, 1 warning (0.11 sec) tidb> show create table t_age\G *************************** 1. row *************************** Table: t_age Create Table: CREATE TABLE `t_age` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin PARTITION BY RANGE (`a`) (PARTITION `p0` VALUES LESS THAN (18), PARTITION `p1` VALUES LESS THAN (35), PARTITION `p2` VALUES LESS THAN (MAXVALUE)) 1 row in set (0.00 sec) -- 分区定义从 RANGE 变更为 LIST tidb> ALTER TABLE t_age PARTITION BY LIST (a) -> ( PARTITION p0 VALUES IN (18) -> , PARTITION p1 VALUES IN (35) -> , PARTITION p2 VALUES IN (65)); Query OK, 0 rows affected, 1 warning (0.12 sec) tidb> show create table t_age\G *************************** 1. row *************************** Table: t_age Create Table: CREATE TABLE `t_age` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin PARTITION BY LIST (`a`) (PARTITION `p0` VALUES IN (18), PARTITION `p1` VALUES IN (35), PARTITION `p2` VALUES IN (65)) 1 row in set (0.00 sec) -- 移除分区 tidb> alter table t_age remove partitioning; Query OK, 0 rows affected (0.10 sec) tidb> show create table t_age\G *************************** 1. row *************************** Table: t_age Create Table: CREATE TABLE `t_age` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin 1 row in set (0.00 sec)!!! Tips 提示:
在分区表定义更新后,建议手动更新统计信息(有些环境可能已经关闭自动更新[14])。
在 PingCAP 公众号最近发布的通告中,TiDB 7.4 发版:正式兼容 MySQL 8.0,详细地介绍了 TiDB 7.4 DMR 在 MySQL 8.0 兼容性方面取得的最新进展。通告中已经列举了若干新特性,本文将做进一步补充。同时,在 TiDB 7.4 DMR 的发版说明中有些小改动并未列出,下面也将进行列举说明,以供参考。
CHECK 约束从 MySQL 8.0.16 开始,MySQL 实现了 CHECK 约束核心特性,并增加了新的信息表 INFORMATION_SCHEMA.CHECK_CONSTRAINTS 用来展示 CHECK 约束定义。[15]
从 TiDB 7.2.0 开始,TiDB 新增支持 CHECK 约束,并在 7.4 中增加表 I_S.CHECK_CONSTRAINTS。需要注意的是,该功能默认关闭,需要通过变量 tidb_enable_check_constraint 进行控制。相关 SQL 控制命令如下:
-- 启用 CHECK 约束功能 SET GLOBAL tidb_enable_check_constraint=ON; -- 添加约束 ALTER TABLE t ADD CONSTRAINT CHECK (1 < a); ALTER TABLE t ADD CONSTRAINT CHECK (1 < a) NOT ENFORCED; -- 删除约束 ALTER TABLE t DROP CONSTRAINT t_chk_1; -- 启用约束 ALTER TABLE t ALTER CONSTRAINT t_chk_1 ENFORCED; -- 禁用约束 ALTER TABLE t ALTER CONSTRAINT t_chk_1 NOT ENFORCED;Ps. 在测试该特性时遇到了两个问题,分别提了 Issue,期待在 TiDB 7.5.0 LTS 代码冻结之前修复。
[Open] CHECK CONSTRAINT loss when ENFORCED again #47567
[Open] Support TABLE_NAME in CHECK_CONSTRAINTS #47565
utf8mb3 字符集;TiDB 7.4.0,支持指定 utf8mb4_0900_ai_ci/utf8mb4_0900_bin 排序规则在之前的文章中,TiDB 6.x 新特性解读 | Collation 规则 ,介绍过 TiDB 的字符集和排序规则,经过若干版本的迭代,TiDB 在全面兼容 MySQL 8.0 的征途上又更进一步。
从 TiDB 7.2.0 开始,支持 utf8mb3 字符集,其作为 utf8 的别名。示例如下:
tidb> create table t_utf8 (a int) charset=utf8; Query OK, 0 rows affected (0.02 sec) tidb> create table t_utf8mb3 (a int) charset=utf8mb3; Query OK, 0 rows affected (0.04 sec) tidb> show create table t_utf8\G *************************** 1. row *************************** Table: t_utf8 Create Table: CREATE TABLE `t_utf8` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin 1 row in set (0.00 sec) tidb> show create table t_utf8mb3\G *************************** 1. row *************************** Table: t_utf8mb3 Create Table: CREATE TABLE `t_utf8mb3` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin 1 row in set (0.00 sec)从 TiDB 7.4.0 开始,支持指定 utf8mb4_0900_ai_ci/utf8mb4_0900_bin 排序规则,在 7.4.0 的发版说明中有这样一段描述[16]:
TiDB v7.4.0 增强了从 MySQL 8.0 迁移数据的支持。新增两个排序规则 (Collation) utf8mb4_0900_ai_ci 和 utf8mb4_0900_bin。其中 utf8mb4_0900_ai_ci 为 MySQL 8.0 的默认排序规则。同时新增支持 MySQL 8.0 兼容的系统变量 default_collation_for_utf8mb4,允许用户为 utf8mb4 字符集指定默认的排序方式,以兼容从 MySQL 5.7 或之前版本迁移或数据复制的场景。
这里需要注意的是,在 TiDB 中,utf8mb4 字符集的默认排序规则仍然是 utf8mb4_bin。
tidb> select @@default_collation_for_utf8mb4; +---------------------------------+ | @@default_collation_for_utf8mb4 | +---------------------------------+ | utf8mb4_bin | +---------------------------------+ 1 row in set (0.00 sec)做个对照实验,更加直观地展示区别:
version() 返回信息变更自 v7.4.0 起,TiDB 已经兼容 MySQL 8.0 的核心功能,version() 将返回以 8.0.11 为前缀的版本信息。[17][18]
补充:MySQL 8.0.11 是 MySQL 8.0 系列的第一个 GA 版本。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。