GreatSQL社区

搜索

GreatSQL社区

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

GreatSQL社区 已有 3 次阅读2025-1-22 10:24 |系统分类:运维实战

数据迁移丨借助 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 version
go 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 源码文件夹后,可以看到以下文件:

$ ls
LICENSE    config.go    migrator_test.go        postgres.go        vendor
Makefile   db.go        mysql.go                postgresrunner     verifier.go
README.md  go.mod       mysqlrunner             testdata           verifier_test.go
cmd        go.sum       pg2mysql_suite_test.go  validator.go       watcher.go
commands   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 -h
2024/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 <<EOF
mysql:
  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: disable
EOF

例如,想迁移 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 validate
users OK

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

$ pg2mysql -c config.yml validate
found 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 --truncate
Disabling constraints...OK
Truncating users...OK
Migrating users...OK
  inserted 1010000 rows
Enabling 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 verify
Verifying 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 选项验证是否按预期迁移

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

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

合作电话:010-64087828

社区邮箱:greatsql@greatdb.com

社区公众号
社区小助手
QQ群
GMT+8, 2025-1-22 15:41 , Processed in 0.041068 second(s), 9 queries , Redis On.
返回顶部