如果您准备将自建PostgreSQL数据库的指定数据库迁移到RDS PostgreSQL实例,同时您已经熟悉pg_dump和pg_restore工具,暂时不希望了解和使用阿里云提供的其他迁移服务(RDS PostgreSQL一键上云功能或数据传输DTS服务)时,您可以参考本文档完成数据库迁移工作。
前提条件
已创建与自建PostgreSQL大版本相同的RDS PostgreSQL实例,具体操作,请参见创建RDS PostgreSQL实例。
说明使用pg_dump和pg_restore迁移数据库时,建议自建PostgreSQL与RDS PostgreSQL实例的大版本相同,以避免兼容问题。
您可以在自建PostgreSQL数据库所在的服务器中,使用
psql --version
命令查询自建数据库的版本。如果您需要升级大版本,可以在迁移完成后,使用大版本升级功能进行升级,更多信息,请参见升级数据库大版本。
如果自建的PostgreSQL数据库服务器位于阿里云ECS,建议在与ECS相同的地域和VPC中创建RDS PostgreSQL实例。使用内网连接进行数据迁移将更快速且更安全。
RDS PostgreSQL实例已配置白名单,允许自建PostgreSQL数据库所在服务器访问,具体操作,请参见设置白名单。
RDS PostgreSQL实例已创建高权限账号,具体操作,请参见创建账号。
已获取RDS PostgreSQL实例的连接地址和端口,具体操作,请参见查看或修改连接地址和端口。
说明如果自建PostgreSQL数据库的服务器是阿里云ECS,且与RDS PostgreSQL在同一地域同一VPC,则获取RDS PostgreSQL实例的内网连接地址和端口,否则,获取外网地址和端口。
自建PostgreSQL数据库已创建superuser权限的管理员账号。
自建PostgreSQL数据库所在服务器已安装pg_dump和pg_restore。
说明在本地安装自建PostgreSQL时,默认安装pg_dump和pg_restore。您可以通过
pg_dump --version
和pg_restore --version
命令查询。
操作步骤
本方案适合于单库迁移。如果需要迁移多个库或整个自建PostgreSQL数据库,请参照如下方案处理。
将自建PostgreSQL数据库中的部分库一次性迁移到RDS PostgreSQL时,建议使用数据库传输DTS进行迁移,更多信息,请参见使用DTS将自建PostgreSQL迁移至RDS PostgreSQL。
将整个自建PostgreSQL数据库迁移上云时,建议使用RDS PostgreSQL提供的一键上云功能,更多信息,请参见一键上云。
步骤一:确认待迁移数据库的相关信息
连接自建PostgreSQL数据库,在psql命令行中,使用\l
查询数据库列表信息,确认待迁移数据库的Owner、Encoding、Collate和Ctype信息。
本文以迁移testdb
数据库为例,Owner为testuser
、Encoding为UTF8
、Collate为en_US.UTF-8
、Ctype为en_US.UTF-8
。
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =Tc/postgres +
| | | | | | | postgres=CTc/postgres
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
testdb | testuser | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
(4 rows)
步骤二:迁移用户
连接自建PostgreSQL数据库所在的服务器,使用如下命令导出待迁移数据库的Owner用户
testuser
。pg_dumpall -g -h 127.0.0.1 -p 5432 -U testuser
返回结果示例:
说明在返回结果中的Roles部分,即可看到导出用户
testuser
的相关权限语句。-- -- PostgreSQL database cluster dump -- SET default_transaction_read_only = off; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; -- -- Roles -- CREATE ROLE postgres; ALTER ROLE postgres WITH SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS; CREATE ROLE testuser; ALTER ROLE testuser WITH SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS PASSWORD 'SCRAM-SHA-256$4096:0IEvNqWupQsGcaoDS3SX****3U='; -- -- User Configurations -- -- -- PostgreSQL database cluster dump complete --
使用高权限账号连接RDS PostgreSQL实例,具体操作,请参见连接PostgreSQL实例。
修改获取的
testuser
用户的相关权限SQL语句(将SUPERUSER
修改为rds_SUPERUSER
),在RDS PostgreSQL实例中创建与自建PostgreSQL权限相同的账号。CREATE ROLE testuser; ALTER ROLE testuser WITH rds_SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS PASSWORD 'SCRAM-SHA-256$4096:0IEvNqWupQsGcaoDS3SX****3U=';
步骤三:在RDS PostgreSQL中创建目标数据库
使用高权限账号连接RDS PostgreSQL实例。
使用如下SQL语句,创建目标数据库,需要确保与自建PostgreSQL中待迁移数据库具有相同字符集、Collate和Ctype。例如步骤一中获取的Encoding为
UTF8
、Collate为en_US.UTF-8
、Ctype为en_US.UTF-8
。CREATE DATABASE <目标数据库的名称> WITH OWNER <数据库Owner名称> TEMPLATE template0 ENCODING 'UTF8' LC_CTYPE 'en_US.UTF-8' LC_COLLATE 'en_US.UTF-8';
说明目标数据库名称可以与自建PostgreSQL中待迁移数据库名称不同。
目标数据库的Owner必须与自建PostgreSQL中迁移数据库Owner相同。
步骤四:数据迁移
本文提供如下数据迁移方案,任选其一即可。
如果您的自建PostgreSQL数据库所在服务器可以直接连接RDS PostgreSQL数据库,则推荐使用在线迁移方式。
如果您的自建PostgreSQL数据库所在服务器无法直接连接RDS PostgreSQL数据库,则推荐使用离线迁移方式,先使用pg_dump导出文件,然后将文件拷贝到能连接RDS PostgreSQL的主机,最后使用pg_restore导入。
在线迁移
配置密码文件。更多信息,请参见The Password File。
在自建PostgreSQL数据库所在服务器执行如下命令创建并编辑.pgpass文件,用于存储密码。
vi ~/.pgpass
按
i
进入编辑模式,输入如下密码相关内容。说明格式为
host:port:dbname:username:password
。dbname和username必须小写,因为PostgreSQL元数据默认使用小写字母存储, 除非您的数据库和用户在创建时使用双引号包括并且大写。
RDS PostgreSQL连接地址:5432:目标数据库名:目标数据库Owner用户名:密码 127.0.0.1:5432:自建PostgreSQL待迁移数据库名:superuser用户名:密码
按
Esc
,输入:wq
退出编辑模式。修改
.pgpass
文件权限。chmod 700 ~/.pgpass
在自建PostgreSQL数据库所在服务器执行如下命令迁移数据。
nohup pg_dump -F p -h 127.0.0.1 -p 5432 -U <自建数据库superuser用户> -d <待迁移数据库> --no-tablespaces | time psql -h <RDS PostgreSQL实例连接地址> -p 5432 -U <目标数据库Owner用户名> --single-transaction <目标数据库> > ./pg.dump.log 2>&1 &
说明您可以查看pg.dump.log文件检查是否存在错误日志,如果该文件为空,则表示迁移成功,可以前往RDS PostgreSQL实例查看迁移后的数据。
上述命令中设置了
--single-transaction
选项,在恢复数据库时将所有操作封装在一个事务中,确保恢复操作要么全部成功,要么全部失败,因此解决报错后可以直接重新导入。
离线迁移
在自建PostgreSQL数据库所在服务器执行如下命令导出文件。
nohup pg_dump -F c -h 127.0.0.1 -p 5432 -U <自建数据库superuser用户> -d <待迁移数据库> --no-tablespaces -f ./pg.dump > ./pg.dump.log 2>&1 &
说明等待导出完成,检查pg.dump.log文件,确认没有报错。
将
pg.dump
文件拷贝到可以连接RDS PostgreSQL实例的主机上,执行如下命令导入文件。说明使用此方案时,需要为RDS PostgreSQL实例配置白名单,允许该主机访问RDS PostgreSQL,具体操作,请参见设置白名单。
单线程导入。
pg_restore -h <RDS PostgreSQL连接地址> -p 5432 -U <目标数据库Owner用户名> -d <目标数据库> --no-tablespaces --single-transaction pg.dump >./pg.restore.log
说明耐心等待导入结束,您可以查看
pg.restore.log
文件检查是否存在错误日志,如果该文件为空,则表示迁移成功,可以前往RDS PostgreSQL实例查看迁移后的数据。上述命令中设置了
--single-transaction
选项,在恢复数据库时将所有操作封装在一个事务中,确保恢复操作要么全部成功,要么全部失败,因此解决报错后可以直接重新导入。
多线程并行导入。
pg_restore -h <RDS PostgreSQL连接地址> -p 5432 -U <目标数据库Owner用户名> -d <目标数据库> --no-tablespaces -j <并行线程数> pg.dump >./pg.restore.log 2>&1 &
说明并行参数
-j
和--single-transaction
参数不能同时使用。参数
-j
的取值范围为正整数,但推荐的最大值为系统CPU核心数的两倍或四倍。这样可以确保充分利用系统资源,同时避免过多的并行任务导致资源竞争和性能下降。因为此方式未使用
--single-transaction
参数进行事务封装,因此一旦恢复过程中报错,则在解决报错后,需要在RDS PostgreSQL侧清空目标数据库下的所有表,再重新开始导入,以确保数据一致性。
相关文档
本文涉及的命令均可根据业务需求配置更多相关参数,具体详见如下官方文档:
本方案适合于单库迁移。如果需要迁移多个库或整个自建PostgreSQL数据库,请参照如下方案处理。
将自建PostgreSQL数据库中的部分库一次性迁移到RDS PostgreSQL时,建议使用数据库传输DTS进行迁移,更多信息,请参见使用DTS将自建PostgreSQL迁移至RDS PostgreSQL。
将整个自建PostgreSQL数据库迁移上云时,建议使用RDS PostgreSQL提供的一键上云功能,更多信息,请参见一键上云。