使用pgloader迁移MySQL到pgSQL

Joe 发布于 28 天前 190 次阅读


基于homebrew的方式安装pgloader

安装pgloader

# 安装pgloader
brew install pgloader

#查看是否安装成功
pgloader --version

添加脚本

创建一个pgload.load文件

load database
     from mysql://migrator:temp123@127.0.0.1:3306/testdb
     into postgresql://postgresql@127.0.0.1/testdb

with include drop, create tables, create indexes, reset sequences
 CAST type datetime to timestamp drop default drop not null using zero-dates-to-null
ALTER SCHEMA 'testdb' RENAME TO 'public';

CAST type datetime to timestamp drop default drop not null using zero-dates-to-null 是为了解决时间类型:MySQL 中是 datetime,转换到 PostgreSQL 为 timestamp with time zone
参考:https://zhuanlan.zhihu.com/p/400282089

遇见的问题

初次执行脚本以下错误:

joezhang@joezhangdeMacBook-Pro kyy % pgloader pgload.load 
2025-12-21T22:15:51.003858-05:00 LOG pgloader version "3.6.9"
2025-12-21T22:15:51.063889-05:00 LOG Migrating from #<MYSQL-CONNECTION mysql://root:123456@127.0.0.1:3306/testdb {700BC8CCB3}>
2025-12-21T22:15:51.064067-05:00 LOG Migrating into #<PGSQL-CONNECTION pgsql://postgresql @127.0.0.1:5432/testdb {700BC8CD43}>
2025-12-21T22:15:51.097699-05:00 ERROR mysql: Failed to connect to mysql at "127.0.0.1" (port 3306) as user "root": Condition QMYND:MYSQL-UNSUPPORTED-AUTHENTICATION was signalled.
2025-12-21T22:15:51.097774-05:00 LOG report summary reset
       table name     errors       rows      bytes      total time
-----------------  ---------  ---------  ---------  --------------
  fetch meta data          0          0                     0.000s
-----------------  ---------  ---------  ---------  --------------

原因:
从 MySQL 8.0 开始,默认的身份验证插件从 mysql_native_password 改为了 caching_sha2_password。

而 pgloader(基于较旧的 MySQL 客户端库)不支持 caching_sha2_password,导致连接失败。

解决方式是创建一个临时用户,并修改身份验证插件:

-- 创建专用用户
CREATE USER 'migrator'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'temp123';
GRANT SELECT, SHOW VIEW ON chestnut_cms2.* TO 'migrator'@'127.0.0.1';
FLUSH PRIVILEGES;

-- 迁移完成后删除
DROP USER 'migrator'@'127.0.0.1';

但是执行是仍然报错,AI最终给出的原因是:
这是 pgloader 在 macOS + MySQL 8.0 下的一个经典兼容性问题,根源在于:

Homebrew 安装的 pgloader 链接的是系统或旧版 libmysqlclient,而该库在与 MySQL 8.0 握手时,即使用户使用 mysql_native_password,仍可能因协议协商失败触发错误。

尽管你设置了兼容插件,但底层 C 客户端库(被 Common Lisp 的 qmynd 调用)在初始化连接时,先尝试协商 caching_sha2_password,如果服务器支持(MySQL 8.0 默认支持),它会优先走新协议 —— 即使你的用户不用它。

而 pgloader 使用的 qmynd 库 不完整支持 caching_sha2_password,于是崩溃并抛出 UNSUPPORTED-AUTHENTICATION。

🔗 相关 issue:

https://github.com/dimitri/pgloader/issues/1042
https://github.com/dimitri/pgloader/issues/950

有两种方案:
一是使用docker安装pgloader
二是临时修改mysql配置文件

这里使用第二种
编辑 MySQL 配置文件(通常是 /opt/homebrew/etc/my.cnf 或 ~/.my.cnf):

[mysqld]
default_authentication_plugin = mysql_native_password

然后重启
brew services restart mysql@8.0

再次执行脚本成功。

最后更新于 2025-12-22