参考:
官方迁移教程:如何使用pgloader迁移MySQL数据库至openGauss (qq.com)
pgloader使用指南PDF
pgloader英文官方文档
前言: pgloader是一款数据导入工具,用于迁移数据到PostgreSQL数据库,因为openGauss是基于postgresql开发的,openGauss兼容PostgreSQL的通信协议以及绝大部分语法,所以可使用pgloader将MySQL数据库迁移至openGauss。
以下演示基于使用docker image方式安装的pgloader。
1、先安装docker
使用root用户执行
具体安装步骤可参考教程:https://cloud.tencent.com/developer/article/1701451
2、拉取pgloader镜像
# 拉取镜像
docker pull dimitri/pgloader:ccl.latest
3、创建用于迁移的openGauss用户
使用omm用户执行
注意:迁移时,pgloader将openGauss当成是PostgreSQL数据库,而PostgreSQL使用MD5的加密规则,openGauss则默认使用sha256,所以为了使openGauss兼容PostgreSQL,需要修改密码加密类型为1:MD5+sha256,否则无法使用pgloader登录openGauss。
解释:password_encryption_type有0,1,2三个值可供选择(默认为2),分别表示:
2:使用sha256;
1:使用md5和sha256;
0:使用md5
# 修改密码加密类型,兼容PostgreSQL
gs_guc reload -D /opt/software/openGauss/data/single_node -c "password_encryption_type = 1"
# 登录openGauss
gsql -d postgres
# 创建用于迁移的用户(需修改加密规则后再创建用户,否则该用户无法以PostgreSQL类型登录)
CREATE USER opengauss_pgloader_user WITH PASSWORD 'gauss_123';
创建用于迁移的兼容性为B的数据库
注意: 这里需先开启enable_global_syscache再创建兼容性为B的数据库,否则会触发bug,导致数据库崩溃。
我一开始就踩了这个bug,后面尝试解决了很久,最后才发现这是一个openGauss的bug,bug的链接:修复enable_global_syscache关闭时连接B兼容性数据库的core问题,有兴趣的可以看下。
该bug已被修复,但我安装的3.0版本是4月1号编译的,该版本还没修复该bug。
# 开启enable_global_syscache
gs_guc reload -N all -I all -c "enable_global_syscache = on"
# 创建用于迁移的兼容性为B的数据库
CREATE DATABASE db_pgloader WITH OWNER opengauss_pgloader_user dbcompatibility='B';
运行pgloader所在的机器需要在openGauss的远程访问白名单中,设置如下:
# -D 后面填写的是数据目录的路径,请自行替换(下同)
gs_guc set -D /opt/software/openGauss/data/single_node -c " listen_addresses = '*'"
# 将xx.xx.xx.xx设置为你机器的IP,特别注意:使用docker进行迁移则ip需设置为docker容器的ip
gs_guc set -D /opt/software/openGauss/data/single_node -h "host all all xx.xx.xx.xx/32 sha256"
# 重启数据库
gs_ctl restart -D /opt/software/openGauss/data/single_node
4、创建MySQL可远程登录的用户
注意: 用户名和IP是mysql.user表的联合主键,二者唯一确定了一个用户,所以root@localhost和root@%是两个用户,他们之间的权限和密码都是独立的,更详细的介绍见教程:
MySQL用户与权限:https://www.jianshu.com/p/b38255b96006
注意:MySQL 5和8版本的命令不同,请选择你对应版本的命令
# MySQL8
# 先创建允许远程访问的用户,'%'表示允许从任意IP登录MySQL
create user 'root'@'%' identified by 'Root@1234';
# 再授予数据库和表的访问权限
grant all privileges on *.* to 'root'@'%' with grant option;
# MySQL5 (创建用户的同时授予权限)
grant all privileges on *.* to root@'%' IDENTIFIED by '你的密码' with grant option;
pgloader不支持MYSQL8默认为caching_sha2_password的authentication plugin,
所以如果想要连上MYSQL8版本的数据库,需要在配置文件my.cnf中添加默认认证插件,如下:
vim /etc/my.cnf
# 添加到[mysqld]下
default-authentication-plugin=mysql_native_password
# 重启mysql服务
systemctl restart mysqld
再将用户的认证插件改为mysql_native_password
命令如下:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '用户密码';
参考:
pgloader运行错误:QMYND:MYSQL-UNSUPPORTED-AUTHENTICATION
解决:https://stackoverflow.com/questions/56542036/pgloader-failed-to-connect-to-mysql-at-localhost-port-3306-as-user-root
5、创建并填写迁移配置文件
切换回root用户执行
创建迁移配置文件:
vim pg.loader
内容如下:
注意:
1:请将数据库账号、密码、IP、迁移的数据库名称修改为你自己的;
2:如果你的数据库密码中有
:
或@
这两个特殊字符,则要对应增加一个:或@,否则pgloader 会无法识别,如果我的密码是 openGauss@123,则在配置文件中我的数据库密码应该写成 openGauss@@123。3:如果你的数据库在本机,IP也不能写成:localhost或127.0.0.1,需将IP设置为具体的本机IP
LOAD DATABASE
FROM mysql://root:Root@@[email protected]:3306/vue_demo
INTO postgresql://opengauss_pgloader_user:[email protected]:5432/db_pgloader
WITH include drop, create tables, create indexes, reset no sequences,workers = 8, concurrency = 1, multiple readers per thread, rows per range = 50000
CAST
type varchar when(= 1 precision) to "boolean" drop typemod keep default keep not null;
6、运行docker容器
docker run -tid --name pgloder.ccl dimitri/pgloader:ccl.latest
7、复制配置文件到容器中
docker cp pg.loader pgloder.ccl:/
8、进入容器,执行迁移
# 进入容器
docker exec -it pgloder.ccl /bin/bash
# 执行迁移
pgloader pg.loader
docker容器命令:
退出容器的命令:
exit
(执行exit后,容器还在后台运行)查看正在运行的docker容器实例(显示CONTAINER ID,NAMES(容器名)等信息):
docker ps
如果想停止实例,则执行:docker stop 容器名;
想移除则执行:docker rm 容器名
更多操作docke容器,见教程:https://www.cnblogs.com/mindzone/p/13363685.html
9、登录openGauss查看迁移结果 (以omm用户执行)
# -d 后面指定数据库名
gsql -d db_pgloader
# 列出所有表:
\dt
# 查询表
select * form xxx
pgloader默认情况下,MySQL的自增整数
会迁移成openGauss的序列整型
类型
openGauss的序列整型本质上是整数加上对应的sequence类型
迁移后在openGauss端会自动创建序列整型
字段对应名称为:表名_自增字段名_seq
的sequence,用该sequence的nextval方法作为字段的默认值,实现自增效果
sequence类型即等差数列,可以指定每次递增多少 (如1)
sequence教程:https://blog.csdn.net/qq_40907977/article/details/104914674
注意:迁移完成后,要使用setval函数
,设置sequence的下一个值 (初始为1)
比如迁移后,要设置tb_fault_event表的sequence字段的下一个值:
# 查询出id的当前最大值,假设结果为363
select max(id) from tb_fault_event
# 设置序列的当前值
select setval('tb_fault_event_id_seq', 363)
例子:
创建表:
CREATE TABLE tb_product (
id bigint DEFAULT nextval('tb_product_id_seq'::regclass) NOT NULL,
server_ip character varying(255) DEFAULT ''::character varying,
product_asset_tag character varying(255) DEFAULT ''::character varying,
delay bigint DEFAULT 1::bigint NOT NULL,
time_unit tb_product_time_unit DEFAULT 'HOURS'::tb_product_time_unit NOT NULL,
create_time timestamp with time zone DEFAULT pg_systimestamp(),
update_time timestamp with time zone DEFAULT pg_systimestamp()
)
创建对应的sequence:
CREATE SEQUENCE tb_product_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
MAXVALUE 9223372036854775807
CACHE 1;
参考:https://blog.csdn.net/liyazhen2011/article/details/82991920
通过CREATE TYPE
自定义类型,其中就有枚举类型:
CREATE TYPE:
在当前数据库中定义一种新的数据类型。定义数据类型的用户将成为该数据类型的拥有者。类型只适用于行存表
有四种形式的CREATE TYPE,分别为:复合类型、基本类型、shell类型和枚举类型。
例子:创建枚举类型,并在建表中使用
create type tb_product_time_unit
as enum('DAYS','HOURS','MINUTES','SECONDS','MILLISECONDS','MICROSECONDS','NANOSECONDS');
CREATE TABLE tb_product (
...
time_unit tb_product_time_unit DEFAULT 'HOURS'::tb_product_time_unit NOT NULL,
)
openGauss的大小写敏感与postgres一致:
pgloader迁移后不会添加双引号,navicat建表会自动添加双引号
openGauss数据库中varchar(n)和char(n)等字符类型中,它的(n),代表的是字节的大小,而不是字符的大小!而utf8编码下一个汉字就占3个字节!
而MySQL数据库中varchar(n)和char(n)的n都指的是字符的大小
这个不兼容的问题可能会导致迁移发生异常!
比如MySQL中某条记录在某个字段char(10)中存了10个汉字(没有问题),但迁移到openGauss中会报错,因为10个汉字的大小已经超过10个字节了。