Skip to content

Instantly share code, notes, and snippets.

@cutecutecat
Last active October 23, 2022 02:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cutecutecat/17e12ec4d5f677ff74482468221e34f9 to your computer and use it in GitHub Desktop.
Save cutecutecat/17e12ec4d5f677ff74482468221e34f9 to your computer and use it in GitHub Desktop.
TiCat设计文档

项目地址 https://github.com/cutecutecat/TiKey 完整版本,可进入初赛评分

TiCat设计文档

  • 团队名称:敲代码不喊我是吧
  • 作者:陈俊羽
  • 项目进展:未开始

项目介绍

项目着眼于实现从MySQL迁移到 TiDB 的迁移校验工具。利用SQL词法解析器和预定义规则,设计一个具有良好拓展性的自动化检查器。

用户使用命令行启动检查器,检查器应能够接收单条sql语句,或者输入一个或者数个sql文件。检查器将检查SQL语句是否符合 TiDB 的要求,确认协议是否能够进行自动迁移。

对于协议不合要求之处,或者存在差异之处,或者无法识别之处,工具将给出建议和相关链接,并给出一个汇总列表,说明存在多少条警告和错误。

背景&动机

项目的背景来自于社区提出的需求:需要一个从MySQL迁移到 TiDB 的迁移校验工具,这样可以提前要求开发对不适配的表结构,存储过程,函数进行改造。

目前PingCap社区对于相关方向,仅有 TiDB Data Migration 工具,它使用 TiDB parser 去解析 DDL 语句。对于TiDB不兼容的语句,将会直接报错退出。对于动辄几百行的SQL协议文件,如果用户直接进行迁移操作,中途可能会报错退出很多次,再进行SQL命令的调整,这一点显著降低了开发效率。

因此,如果能够提供一个工具,能够以标准 MYSQL 语法而非 TiDB 语法,对 SQL 文件进行全文扫描,并给出所有的不兼容语句和修改建议。用户即可根据检查报告,对所有不兼容语句进行修改,有益于加速数据库迁移工作流。

项目设计

因为项目可能需要用于检测海量的 SQL 文件,对性能会有一定的要求,我们拟采用 Rust 语言进行开发。

检查器首先将注册每条规则与对应的触发条件。例如:外键约束在TiDB中不兼容,对于这一条规则,检查器需要检查所有的CREATE TABLE 语句是否携带FOREIGN KEY参数。

graph TD
A[Rule A] --> Z[Rule Registry]
B[Rule B] --> Z[Rule Registry]
C[Rule C] --> Z[Rule Registry]
D[Rule D] --> Z[Rule Registry]
E[Rule E] --> Z[Rule Registry]

为了实现这一点,检查器需要工作在SQL语句的AST语法树上,我们引入 sqlparser 库进行SQL的词法解析。但是,考虑到 sqlparser 只能解析 DML 语句和部分 DDL 语句,例如自定义函数语句 CREATE FUNCTIONsqlparser 会被解析失败,我们在使用了 sqlparser 的基础上,拓展了几种不兼容,但我们的检查器需要检查出的词法解析场景。

img

考虑到 Rust 无法使用反射对结构体进行迭代,我们使用 serde_json 库将AST序列化为可迭代的数据类型 Value ,依次迭代每个键值对,并同步校验是否符合规则集。

在数据结构的设计上,为了保证O(1)复杂度的规则匹配,我们拟使用哈希表存储规则和Key的关联。

输出示例

汇总报告

file count 5 SQL count 58
warning 15 error 3
time cost 1.14s

从上到下分别为:输入文件数量、输入SQL语句数量、警告数量、报错数量、检查耗时。

单条报告

level error
version Earliest - Newest
future will support
info Not supported "Foreign Key"
url pingcap/tidb#18209
sql CREATE TABLE t2 (  id INT NOT NULL PRIMARY KEY auto_increment,  t1_id INT NOT NULL,  b CHAR(32) NOT NULL,  FOREIGN KEY (t1_id) REFERENCES t1(id) );

从上到下分别为:等级(错误)、影响版本(最早版本到最新版本)、未来计划(将会支持)、描述、相关链接、错误语句。

@innerr
Copy link

innerr commented Oct 17, 2022

Another project related to TiDB has the same name: https://github.com/innerr/ticat

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment