前言
我这边接到一个数据库国产化适配的工作,需要将MySQL数据全量迁移到OpenGauss中,我第一个想到的就是使用OpenGauss官方的数据迁移工具,就是这个工具:openGauss-migration-portal
我按照官方文档的步骤来,但是执行后报错了,我折腾大概要3小时,最后放弃使用这个官方工具了并留下了一个issue。然后我发现遇到同样问题的人不止我一个,且这个问题在2024年4月28日就提出了,到现在2025年7月3日都没有修复!
由于迁移工具chameleon还是Python写的,而且整个项目极其复杂,我已经不想去改他们的bug了,什么gp官方,还不如我自己来!做到全程自主可控!
建表语句区别
由于OpenGauss是基于PostgreSQL的,因此其建表语句和MySQL差别巨大,需要将MySQL表结构转为PostgreSQL表结构。
其中区别包括:
VARCHAR要改为NVARCHAR2,不然中文字符存放量会缩小3倍!因为utf-8一个中文字符占3个字节,而OpenGauss的VARCHAR是计算字节数而不是字符数,这会导致存储的数据量大大下降,会导致列数据溢出,而NVARCHAR2计算的是字符数而不是字节数,能与MySQL保持一致。
不存在DATETIME,要改为TIMESTAMP。
OpenGauss存在BOOLEAN类型,可以将TINYINT(1)改为BOOLEAN,BIT(1)也要改为BOOLEAN类型。
DOUBLE要改为DOUBLE PRECISION,FLOAT要改为REAL。
BINARY要改为BTYEA。
各种TEXT类型要改为TEXT类型。
OpenGauss的索引是全局的,而MySQL的是基于表的,因此可能会出现索引重名的情况,因此需要在索引全加上表名,防止出现索引名冲突。
但是索引名又有长度限制,不能超过31个字符,因此还得做长度截取。
分区表的写法和MySQL完全不同,需要进行转换。
字段注释是额外写的,需要将所有字段的字段注释整理出来,在建完表后执行单独的SQL进行字段注释。
分析MySQL建表语句
由于MySQL普通用户大概率是没有information_schema权限的,因此不能通过查询这个库来获取所有表信息了,那只能执行:
sql
show create table 表名
获取该表的建表语句,也就是ddl信息,通过解析每行数据,比如存在KEY说明这个是索引,如果是Partition则说明是分区表信息。除了这些,再排除第一行,其他就是各个列信息了,通过分析字符串将表结构全部解析出来。
重新生成OpenGauss建表语句
有了整个MySQL的建表信息,只需要重组建表语句即可。
这里分为4段信息:
第一段:建表语句包括其中所有字段名称和类型。
第二段:分区表信息。注意!OpenGauss的分区表建表语句和PostgreSQL是完全不同的!
第三段:索引信息。OpenGauss/PostgreSQL的索引和表是完全分开的,且是全局的。
第四段:表注释和字段注释。这些注释信息和建表语句也是完全分开的。
其中还有一个大坑就是MySQL中的关键字不一定是OpenGauss的关键字,也就是说你在MySQL中没问题的字段名,搬到OpenGauss中可能就报错了!需要使用双引号进行转义。
传输数据到OpenGauss
最难的其实还是表结构转换,完成结构转换后其他就简单多了。主要就是查询MySQL中的数据,然后插入到OpenGauss中。
MySQL查询不能全部查出来,如果数据量很大的话,内存就要爆咯,必须使用分页查询。分页查询需要注意不要使用limit和offset,这个效率会很低,建议使用主键大于某个值,类似于Elasticsearch的滚动查询,能够显著提高查询效率。
另外可以使用线程池提高传输效率,但是需要加装一个阀门,不然大量任务一次性提交到线程池中恐怕内存也会吃不消。
最后就是转义问题了,比如查询出来的数据存在单引号和反斜杠,如果你拿这种数据直接插入数据库,那就要翻车了,需要对这些特殊符号进行转义才能入库。
开源项目
介绍了这么多,大家一定会觉得这个传输确实有点麻烦了,有没有开源项目可以直接用呢?那我可要忍不住了,这就把我自己写的MySQL迁移OpenGauss的项目推荐给大家:
https://gitee.com/decentant/mysql-to-opengauss
项目说明已经在README中写得很清楚了,而且代码并不复杂。安装包大小仅26MB,相比于官方动辄639MB的安装包可以说是只是个零头了。
执行完成后还有报表信息,可以直观看到哪些表迁移失败,具体报错信息也一目了然。
执行结果


迁移过程中有些表失败其实很正常,比如建表的时候不规范,或者有一些特殊类型我没照顾到,大家看报错信息自己修复一下,或者给我的项目提Merge Request都行。