亚马逊AWS官方博客
使用 pg_dump 将云下 PostgreSQL 迁移到AWS RDS PostgreSQL最佳实践
前言
本文主要讲述在将云下 PostgreSQL 数据库迁移到 RDS PostgreSQL 的指导原则及最佳实践,这里主要通过pg_dump来完成迁移。
关于 RDS PostgreSQL
PostgreSQL 号称“世界上最先进开源关系型数据库”,其本身功能丰富而强大,经过30多年的积极开发,在可靠性,功能稳健性和性能方面赢得了良好的声誉。PostgreSQL 已成为许多企业开发人员和初创公司的首选开源关系数据库。Amazon RDS 让用户能够在云中轻松设置、操作和扩展 PostgreSQL 部署。借助 Amazon RDS ,你可以在几分钟内完成可扩展的 PostgreSQL 部署,不仅经济实惠,而且可以调整硬件容量。Amazon RDS 可管理复杂而耗时的管理任务,例如 PostgreSQL 软件安装和升级、存储管理、为获得高可用性和高读取吞吐量而进行的复制,以及为灾难恢复而进行的备份。
借助 Amazon RDS for PostgreSQL,你可以访问非常熟悉的 PostgreSQL 数据库引擎的功能。这意味着你当前用于现有数据库的代码、应用程序和工具也可以用于 Amazon RDS 。Amazon RDS 支持 PostgreSQL 主要版本 11,该版本包括对性能、可靠性、事务管理和查询并行性等方面的多项增强。
只需在 AWS 管理控制台中单击几下鼠标,即可使用自动配置的数据库参数部署 PostgreSQL 数据库,以获得最佳性能。Amazon RDS for PostgreSQL 数据库既可以按照标准存储模式预置,也可以按照预配置 IOPS 模式配置。预置完成后,你可以扩展到 16TB 的存储容量和 40000 IOPS。此外,Amazon RDS for PostgreSQL 还支持你进行扩展并超出单个数据库部署的容量,以便处理高读取量的数据库工作负载。
迁移注意事项
- 在 RDS PostgreSQL 里出于安全上的考虑,并没有 superuser 和 replication 角色,对应的是 rds_superuser 和 rds_replication
- 本地 PostgreSQL 我们通常会安装在 postgres 用户下,这个时候在 PostgreSQL 中对应的就会有一个 postgres 超级用户,在 RDS PostgreSQL 中缺省没有此用户
- 由于 RDS PostgreSQL 的主用户( master user )并不具备 superuser 权限,这就导致很多在云下使用 pg_dump 进行数据迁移可以正常执行的命令,在 RDS 上执行会报错
数据库迁移过程
环境说明:云下 PostgreSQL 版本为9.6.12,RDS PostgreSQL 版本为9.6.11。
使用 pg_dumpall 导出角色/用户创建脚本
修改角色/用户创建脚本
依次按如下内容修改role.sql脚本文件,保存为role_change.sql:
- 去掉所有的 CREATE ROLE 语句
- 将带有 WITH 选项的 ALTER ROLE 语句全部替换为 CREATE ROLE
- 去掉 postgres 用户,这是本地 PostgreSQL 的 superuser 用户, RDS 上没有此用户,故使用 master user 代替
使用 pg_dump 按数据库分别导出
这里以 testuserbb 数据库为例进行操作
修改导出文件
改动内容:
- 将 OWNER TO postgres 调整为 OWNER TO root ,这里的root为RDS PostgreSQL的master user
- 将 OWNER TO testuserbb 调整为 OWNER TO root
如下使用 grep 命令过滤出来的红色高亮部分内容,这里请先保留下来,在数据导入完成之后需要执行这些命令。
[postgres@ip-172-31-46-20 ~]$ cat testuserbb.sql | grep “OWNER TO”
ALTER DATABASE testuserbb OWNER TO postgres;
ALTER TABLE public.flyway_schema_history OWNER TO testuserbb;
ALTER TABLE public.role_permission OWNER TO testuserbb;
ALTER TABLE public.role_permission_id_seq OWNER TO testuserbb;
ALTER TABLE public.sys_permission OWNER TO testuserbb;
ALTER TABLE public.sys_permission_id_seq OWNER TO testuserbb;
ALTER TABLE public.sys_role OWNER TO testuserbb;
ALTER TABLE public.sys_role_id_seq OWNER TO testuserbb;
ALTER TABLE public.sys_user OWNER TO testuserbb;
ALTER TABLE public.sys_user_id_seq OWNER TO testuserbb;
ALTER TABLE public.sys_user_operation_log OWNER TO testuserbb;
ALTER TABLE public.sys_user_operation_log_id_seq OWNER TO testuserbb;
ALTER TABLE public.user_role OWNER TO testuserbb;
ALTER TABLE public.user_role_id_seq OWNER TO testuserbb;
[postgres@ip-172-31-46-20 ~]$ sed -i ‘s/postgres/root/g’ testuserbb.sql
[postgres@ip-172-31-46-20 ~]$ sed -i ‘s/OWNER TO testuserbb/OWNER TO root/g’ testuserbb.sql
[postgres@ip-172-31-46-20 ~]$ cat testuserbb.sql | grep “OWNER TO”
ALTER DATABASE testuserbb OWNER TO root;
ALTER TABLE public.flyway_schema_history OWNER TO root;
ALTER TABLE public.role_permission OWNER TO root;
ALTER TABLE public.role_permission_id_seq OWNER TO root;
ALTER TABLE public.sys_permission OWNER TO root;
ALTER TABLE public.sys_permission_id_seq OWNER TO root;
ALTER TABLE public.sys_role OWNER TO root;
ALTER TABLE public.sys_role_id_seq OWNER TO root;
ALTER TABLE public.sys_user OWNER TO root;
ALTER TABLE public.sys_user_id_seq OWNER TO root;
ALTER TABLE public.sys_user_operation_log OWNER TO root;
ALTER TABLE public.sys_user_operation_log_id_seq OWNER TO root;
ALTER TABLE public.user_role OWNER TO root;
ALTER TABLE public.user_role_id_seq OWNER TO root;
[postgres@ip-172-31-46-20 ~]$
将上述橙色高亮部分替换导出文件testuserbb.sql最后的如下四条命令:
导入数据:执行角色/用户创建脚本
这里以RDS master user执行:
导入数据:执行数据脚本
忽略出现的comment on extension执行报错。
查看导入的数据
这里我们看到导入表的 owner 都已经调整为 root 了( RDS 的 master user ),因此原先的用户没有查询权限。
调整属主为原用户
以 root 用户( RDS master user )执行<修改导出文件>章节红色高亮的命令
ALTER TABLE public.flyway_schema_history OWNER TO testuserbb;
ALTER TABLE public.role_permission OWNER TO testuserbb;
ALTER TABLE public.role_permission_id_seq OWNER TO testuserbb;
ALTER TABLE public.sys_permission OWNER TO testuserbb;
ALTER TABLE public.sys_permission_id_seq OWNER TO testuserbb;
ALTER TABLE public.sys_role OWNER TO testuserbb;
ALTER TABLE public.sys_role_id_seq OWNER TO testuserbb;
ALTER TABLE public.sys_user OWNER TO testuserbb;
ALTER TABLE public.sys_user_id_seq OWNER TO testuserbb;
ALTER TABLE public.sys_user_operation_log OWNER TO testuserbb;
ALTER TABLE public.sys_user_operation_log_id_seq OWNER TO testuserbb;
ALTER TABLE public.user_role OWNER TO testuserbb;
ALTER TABLE public.user_role_id_seq OWNER TO testuserbb;
切换到 testuserbb 数据库以 root 用户连接:
问题说明
错误01: comment on extension 执行报错
comment on extension 只是给 extension 添加一个注释,并不影响实际使用,可以忽略。另外, plpgsql 缺省在 RDS 里就已经有了,不需再进行创建。可以使用 \dx命令确认一下:
错误02: public SCHEMA 赋权命令执行报错
如下4条命令执行会报错: