写点什么

数据迁移丨借助 pg2mysql 从 PostgreSQL 到 GreatSQL

作者:GreatSQL
  • 2025-01-22
    福建
  • 本文字数:3608 字

    阅读完需:约 12 分钟

数据迁移丨借助 pg2mysql 从 PostgreSQL 到 GreatSQL

上篇《数据迁移丨借助 AI 从 PostgreSQL 到 GreatSQL》介绍了如何使用 AI + pg_dump/COPY 的方式将 PostgreSQL 迁移到 GreatSQL 中,各位同学看过之后,会发现两款数据库还是有一些差异,例如对象层次结构、数据类型等方面,如果采用人工来迁移,还是会比较麻烦,所以本篇将介绍,如何使用开源工具 pg2mysql 工具从 PostgreSQL 到 GreatSQL。

pg2mysql 简介

pg2mysql 工具是一款开源工具,由 VMware 公司提供,主要用于将数据从 PostgreSQL 迁移至 MySQL 或 GreatSQL。其核心价值在于数据兼容性检查与迁移功能。在实际迁移操作之前,该工具会仔细检查 MySQL/GreatSQL 的表结构与 PostgreSQL 中相应表结构是否兼容。若检测到诸如字段长度不足之类的潜在问题,它会向用户发出提示,以便用户进行修正。


pg2mysql 工具主要是用 Go 语言编写的,遵循 Apache - 2.0 许可证。不过需要注意的是,目前这个项目已经归档,不再进行定期更新了。但对于有能力的朋友而言,可以基于该项目进行进一步的开发:)


pg2mysql 安装

方式一:下载程序


以上链接可以直接下载 pg2mysql 最新 v0.0.6 版本,授权后可直接运行:


$ chomd 755 pg2mysql_linux
$ ./pg2mysql_linux -h 2024/10/28 14:52:40 error: Usage: pg2mysql_linux [OPTIONS] <migrate | validate | verify>
Application Options: -c, --config= Path to config file
Help Options: -h, --help Show this help message
Available commands: migrate Migrate data from PostgreSQL to MySQL validate Validate that the data in PostgreSQL can be migrated to MySQL verify Verify migrated data matches
复制代码

方式二:源码安装

源码安装方式需要有 GO 语言环境:


$ go versiongo version go1.22.5 linux/amd64
复制代码


版本没有强要求,go1.22.5 版本可以正常编译运行。


新建一个文件夹,用于存放 pg2mysql 工具源码:


$ mkdir /usr/local/pg2mysql$ cd /usr/local/pg2mysql
复制代码


拉取 pg2mysql 工具源码:


$ git clone https://github.com/pivotal-cf/pg2mysql.git$ cd pg2mysql/
复制代码


如果采用手册中的方法go get github.com/pivotal-cf/pg2mysql/cmd/pg2mysql

会报错:

go: go.mod file not found in current directory or any parent directory. 'go get' is no longer supported outside a module. To build and install a command, use 'go install' with a version, like 'go install example.com/cmd@latest' For more information, see https://golang.org/doc/go-get-install-deprecation or run 'go help get' or 'go help install'.

是因为目前新版本 Go 语言在模块(module)相关的使用方式上有了变化,直接先拉取源码在操作。


进入 pg2mysql 源码文件夹后,可以看到以下文件:


$ lsLICENSE    config.go    migrator_test.go        postgres.go        vendorMakefile   db.go        mysql.go                postgresrunner     verifier.goREADME.md  go.mod       mysqlrunner             testdata           verifier_test.gocmd        go.sum       pg2mysql_suite_test.go  validator.go       watcher.gocommands   migrator.go  pg2mysqlfakes           validator_test.go
复制代码


接下来构建项目:


$ go mod init pg2mysql$ go mod tidy
复制代码


构建完成后,可以编译该工具:


$ go build -o pg2mysql cmd/pg2mysql/main.go
复制代码


在文件夹下就会发现 main 可执行文件,接着授权即可运行:


# 授权$ chmod 755 pg2mysql 
# 授权完成即可运行$ ./pg2mysql -h2024/10/30 13:58:20 error: Usage: pg2mysql [OPTIONS] <migrate | validate | verify>
Application Options: -c, --config= Path to config file
Help Options: -h, --help Show this help message
Available commands: migrate Migrate data from PostgreSQL to MySQL validate Validate that the data in PostgreSQL can be migrated to MySQL verify Verify migrated data matches
复制代码


这里有 error 没关系,看源码可知 log.Fatalf("error: %s", err) 会带有一个error,并不是无法使用。

pg2mysql 使用

创建配置

首先需要创建配置,创建 PostgreSQL 和 MySQL/GreatSQL 的链接信息:


$ cat > config.yml <<EOFmysql:  database: some-dbname  username: some-user  password: some-password  host: 192.168.10.1  port: 3306
postgresql: database: some-dbname username: some-user password: some-password host: 192.168.10.2 port: 5432 ssl_mode: disableEOF
复制代码


例如,想迁移 PostgreSQL 数据库 pg_to_greatsql 库下的 users 表到 GreatSQL 数据库:


mysql:  database: pg_to_greatsql  username: root# GreatSQL 密码设置的是空  password:   host: 192.168.6.88  port: 3306
postgresql: database: pg_to_greatsql username: postgres password: GreatSQL@666 host: 192.168.6.52 port: 5432 ssl_mode: disable
复制代码


这里有两个问题:


  1. PostgreSQL 数据库的 ssl_mode 参数


ssl_mode 参数可以看:



设置为 disable 指的是 I don't care about security, and I don't want to pay the overhead of encryption. 意思就是不关心安全性也不加密。


  1. 两个数据库的远程链接


GreatSQL 和 PostgreSQL 都有远程链接限制需要打开。GreatSQL 打开方式可以阅读:


建库建表

pg2mysql 工具不支持协助建库建表,所以需要自行建库建表。可以参考上篇,利用 AI 协助建表:


  • 数据迁移丨借助 AI 从 PostgreSQL 到 GreatSQL


搜索关键词 表结构迁移 即可跳转对应内容。

验证数据

建库建表完成后,使用参数 validate 验证:


$ pg2mysql -c config.yml validateusers OK
复制代码


如果没有问题的话,会显示 OK。如果有问题的话会显示以下内容:


$ pg2mysql -c config.yml validatefound incompatible rows in apps with IDs [2]found incompatible rows in app_usage_events with IDs [9 10 11 12]found incompatible rows in events with IDs [16 17 18]
复制代码


如果存在任何不兼容的行(如上所述),则需要在继续迁移之前对其进行修改。

迁移数据

验证完成以后,就可以使用 migrate 迁移数据了:


$ pg2mysql -c config.yml migrate --truncateDisabling constraints...OKTruncating users...OKMigrating users...OK  inserted 1010000 rowsEnabling constraints...OK
复制代码


!!!注意!!!

--truncate 命令会清空目标表,作用是保证数据一致,如果目标表有数据,请不要使用该参数。


阅读源码可知,迁移的方式也是采用 INSERT INTO的 SQL 语句:


// pg2mysql 中 migrator.go 的源码preparedStmt, err := m.dst.DB().Prepare(fmt.Sprintf(            "INSERT INTO %s (%s) VALUES (%s)",            table.Name,            strings.Join(columnNamesForInsert, ","),            strings.Join(placeholders, ","),        ))        if err != nil {            return fmt.Errorf("failed creating prepared statement: %s", err)        }
复制代码


如果大数据迁移,肯定会很慢,可以考虑关闭双 1 等方法提高插入速度。

验证数据

迁移后运行验证程序以确认数据已按预期迁移:


$ pg2mysql -c config.yml verifyVerifying table users...OK
复制代码


验证对 PostgreSQL 中每个表的每一行的内容进行精确比较,以查看 GreatSQL 中是否存在匹配的行。


根据源码,该工具会遍历源数据库中的所有表,遍历源数据库中的每一行,然后在判断行是否存在于目标数据库中:


// 例如下面的代码,准备检查目标数据库中是否存在行的语句stmt = fmt.Sprintf(`SELECT EXISTS (SELECT 1 FROM %s WHERE %s)`, table.Name, strings.Join(colVals, " AND "))    preparedStmt, err := dst.DB().Prepare(stmt)    if err != nil {        return fmt.Errorf("failed to prepare statement: %s", err)    }
复制代码


这就导致了会使得该操作异常的慢。

进阶使用

pg2mysql 工具虽然可以简化迁移的流程,但是速度和效率来说有点太慢了,当然速度和源端/目标端的机器配置决定的,但是方法是采用大数量级的 INSERT INTO 还是会对数据库产生不小的负载。所以我推荐可以试着采用下面的方法:


  1. 先使用 AI 协助迁移 库/表 结构

  2. 在使用 pg2mysql -c config.yml validate 选项验证是否兼容

  3. 采用 PostgreSQL COPY 导出文件

  4. 使用 GreatSQL Load Data 特性导入

  5. 导入后使用 pg2mysql -c config.yml verify 选项验证是否按预期迁移


当然,有能力的同学也可以将该工具优化下:)


发布于: 23 小时前阅读数: 2
用户头像

GreatSQL

关注

GreatSQL社区 2023-01-31 加入

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。 社区:https://greatsql.cn/ Gitee: https://gitee.com/GreatSQL/GreatSQL

评论

发布
暂无评论
数据迁移丨借助 pg2mysql 从 PostgreSQL 到 GreatSQL_GreatSQL_InfoQ写作社区