如何在RDS实例内复制PostgreSQL RDS数据库

10

我在这方面遇到了很多麻烦 - 我想在StackOverflow上发布一个问答,以解释这个过程。

问题是关于将RDS postgres数据库复制为开发使用 - 特别是测试数据库迁移脚本等。这就是为什么需要关注“单个数据库”中的“单个模式”的原因。

在我的情况下,我希望创建一个尽可能隔离的测试数据库,同时仍然在单个RDS实例内(因为启动整个RDS实例需要5-15分钟,而且我很抠门)。

2个回答

14

以下是仅使用命令行的答案。

前提条件:

  • 您必须安装了Postgres客户端工具(不需要实际的服务器)
    • 客户端版本必须与您的postgres服务器版本相同或更高
  • 可以访问RDS实例的网络
  • 访问相关数据库帐户的凭据

示例上下文:

  • 我在rds.example.com上有一个RDS实例,其中有一个名为rds_master的主用户。
  • 我有一个名为db_dev_user的“应用程序用户”,一个名为dev_db的数据库,其中包含模式app_schema
  • 请注意,postgres中的“用户”和“角色”是同义词

注意:此指南是在2017年编写的,适用于postgres 9.6版本。 如果您发现某些步骤在最近的postgres版本上不再起作用-请将任何修复步骤发布为评论或备选答案。


pg_dump会打印出原始数据库的模式和数据,即使在数据库存在活动连接时也可以正常工作。当然,这些连接的性能可能会受到影响,但所得到的DB副本是transactional

pg_dump --host=rds.example.com --port=5432 \
  --format=custom \
  --username=db_dev_user --dbname=dev_db \
  > pgdumped

createuser命令用于创建测试应用程序/进程应连接的用户(以实现更好的隔离),请注意,创建的用户不是超级用户,因此无法创建数据库或角色。

createuser --host=rds.example.com --port=5432 \
  --username=rds_master \
  --no-createdb --no-createrole --no-superuser \
  --login --pwprompt \
  db_test_user

如果没有下一个grant命令,接下来的createdb将会失败:

psql --host=rds.example.com --port=5432 \
  --username=rds_master --dbname=postgres \
  --command="grant db_test_user TO rds_master"

createdb按照字面意思创建数据库;注意db_test_user角色“拥有”该数据库。

createdb --host=rds.example.com --port=5432 \
  --username=rds_master --owner=db_test_user test_db

下一个命令是“创建模式”。用户“db_test_user”无法创建模式,但必须对模式进行授权,否则“pg_restore”会失败,因为它会尝试还原到“pg_catalog”模式中(请注意,“user=rds_master”,但“dbname=test_db”)。
psql --host=rds.example.com --port=5432 \
  --username=rds_master --dbname=test_db \
  --command="create schema app_schema authorization db_test_user"

最后,我们使用pg_restore命令来创建模式对象(表等)并将数据加载到其中:

pg_restore --host=rds.example.com --port=5432 \
  --verbose --exit-on-error --single-transaction \
  --username=db_test_user --schema=app_schema \
  --dbname=test_db --no-owner \
  ./pgdumped
  • exit-on-error - 因为否则查找错误需要太多的滚动和扫描(同时也被single-transaction暗示)
  • single-transaction - 避免在出现问题时必须删除或重新创建数据库
  • schema - 只处理我们关心的模式(也可以将其提供给原始的pg_dump命令)
  • dbname - 确保使用我们创建的数据库
  • no-owner - 我们正在连接作为db_test_user,所以所有内容应该由正确的用户拥有

6

对于生产环境,最好只需对实例进行RDS快照并恢复,这将创建一个全新的RDS实例。

在大多数情况下空数据库上 - 创建快照需要几分钟时间,另外还需要约5分钟时间来创建新的RDS实例(这也是为什么在开发过程中很麻烦的原因之一)。

只有当新的RDS实例运行时才会收取费用。保持在免费层内是我想要使用相同的实例为开发目的创建此DB的原因之一,再加上不必处理第二个DNS名称;随着您开始拥有多个小型开发环境,这种效果会成倍增加。

运行第二个RDS实例是生产环境的更好选择,因为它几乎完全消除了对原始DB的任何风险。此外,当您处理实际数据量时 - 快照/DB创建时间将被读取/写入数据所花费的时间所超越。对于大量数据,Amazon RDS快照创建/恢复过程可能会比在单个服务器上运行的一组脚本具有更好的并行性。此外,RDS控制台可以让您看到恢复进度 - 随着数据集变得越来越大并且越来越多的人参与其中,这变得非常宝贵。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接