2019 年的时候已经简单写过一篇类似的内容,但是当时写的比较粗糙,使用也比较简单。
恰好 2023 年的时候在处理类似的迁移需求时,面对的数据量较大,情况也较为复杂,所以本次进一步完善 pgloader 的安装与使用说明。
安装
https://github.com/dimitri/pgloader
https://github.com/dimitri/pgloader/releases
简单说,推荐使用打包好了的,不必在编译时获取构建依赖项的版本,在 releases 中下载即可。
# 安装
tar -xf pgloader-bundle-3.6.9.tgz
cd pgloader-bundle-3.6.9
make pgloader
# 配置别名
vi ~/.bashrc
alias pgloader=/home/{user}/pgloader-bundle-3.6.9/bin/pgloader
source ~/.bashrc
# 测试输出
pgloader --version
pgloader version "3.6.9"
compiled with SBCL 1.4.0-1.el7
使用
https://pgloader.readthedocs.io/en/latest/
https://pgloader.readthedocs.io/en/latest/command.html
https://pgloader.readthedocs.io/en/latest/ref/mysql.html#mysql-database-migration-options-with
https://pgloader.readthedocs.io/en/latest/ref/mysql.html#mysql-database-casting-rules
https://pgloader.readthedocs.io/en/latest/ref/mysql.html#default-mysql-casting-rules
https://pgloader.readthedocs.io/en/latest/ref/transforms.html
使用编写迁移脚本的方式,执行脚本:
pgloader my.load
命令语法
LOAD <source-type>
FROM <source-url>
[ HAVING FIELDS <source-level-options> ]
INTO <postgresql-url>
[ TARGET TABLE [ "<schema>" ]."<table name>" ]
[ TARGET COLUMNS <columns-and-options> ]
[ WITH <load-options> ]
[ SET <postgresql-settings> ]
[ BEFORE LOAD [ DO <sql statements> | EXECUTE <sql file> ] ... ]
[ AFTER LOAD [ DO <sql statements> | EXECUTE <sql file> ] ... ]
;
WITH
用于指定应用于迁移过程的选项。
- include drop
删除目标库中已有的同名表。 - create tables
使用 MySQL 文件中的元数据创建表。 - create indexes
基于 MySQL 库中的索引定义为 PostgreSQL 库创建相同的索引。 - reset sequences
在数据加载结束以及索引全部创建后,将创建的所有 PostgreSQL 序列重置为它们所附加列的当前最大值。
SET
用于设置会话参数。
pgloade 不对参数的名称和值进行验证,它们是按原样提供给 PostgreSQL 的。
CAST
用于指定或者重载默认的转换规则。
例子中的规则用来处理空间数据,以及处理 MySQL 中日期的零值(0000-00-00 00:00:00
)问题。
INCLUDING ONLY TABLE NAMES MATCHING
指定迁移的表名,支持正则表达式。
例子中含义为迁移表名首字母为 a 至 c 之间的表,以及 tb_name1、tb_name2 。
EXCLUDING TABLE NAMES MATCHING
指定不迁移的表名,即排除的表名,支持正则表达式。
例子中含义为不迁移表名为 act 开头表,copy 加数字结尾的表,以及 tb_name3、tb_name4 。
ALTER SCHEMA ‘…’ RENAME TO ‘…’
修改 postgres 库中的 schema 名称。
由于 MySQL 向 Postgres 迁移时,默认使用 MySQL 的库名作为 Postgres 库中的 schema 名称,而通常 Postgres 库中使用的 schema 是 public 。
BEFORE LOAD DO
在加载数据之前对 postgres 库执行的 SQL。
这里用来创建 postgis 扩展。
注意如果对一个库分多次(多个命令文件)执行,只在第一个命令文件中需要写。
典型命令文件:
LOAD DATABASE
FROM mysql://root:{passwd}@localhost:3306/{mysql_dbname}
INTO pgsql://postgres:{passwd}@localhost:5432/{postgres_dbname}
WITH include drop, create tables, create indexes,
workers = 8, concurrency = 1,
multiple readers per thread, rows per range = 1000,
prefetch rows = 1000, batch rows = 1000
SET PostgreSQL PARAMETERS
maintenance_work_mem to '512MB',
work_mem to '48MB'
SET MySQL PARAMETERS
net_read_timeout = '3600',
net_write_timeout = '3600'
CAST type point to "GEOMETRY(POINT)",
type linestring to "GEOMETRY(LINESTRING)",
type datetime to timestamp drop default drop not null using zero-dates-to-null
INCLUDING ONLY TABLE NAMES MATCHING ~/^[a-c]/, 'tb_name1', 'tb_name2'
EXCLUDING TABLE NAMES MATCHING ~/^act/, ~/copy[0-9]*$/, 'tb_name3', 'tb_name4'
ALTER SCHEMA '{mysql_dbname}' RENAME TO 'public'
BEFORE LOAD DO
$$ CREATE EXTENSION postgis; $$
;