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

Sho*_*orn 3 postgresql amazon-rds

这样做我遇到了很多麻烦 - 我想我会在StackOverflow上做一个Q/A来解释这个过程.

问题是关于复制RDS postgres数据库以供开发使用 - 尤其是测试数据库迁移脚本等.这就是为什么要关注"单个数据库"中的"单一模式".

在我的情况下,我想创建一个尽可能隔离的测试数据库,同时保留在一个RDS实例中(因为整个RDS实例的旋转需要5到15分钟,因为我很便宜).

Sho*_*orn 9

这是仅使用命令行的答案.您必须安装Postgres客户端工具(不需要实际服务器)和对RDS实例的网络访问.

在下面的示例中:

  • 我有一个RDS实例,rds.example.com其中有一个名为的主用户rds_master.
  • 我有一个名为"应用程序用户" db_dev_user,名为dev_db包含架构的数据库app_schema.
  • 请注意,postgres中的"user"和"role"是同义词

pg_dump打印出原始数据库的模式和数据,即使存在与数据库的活动连接也会起作用(当然,这些连接的性能可能会受到影响):

pg_dump --host=rds.example.com --port=5432 \
  --format=custom \
  --username=db_dev_user --dbname=dev_db \
  > pgdumped
Run Code Online (Sandbox Code Playgroud)

该CREATEUSER命令创建测试应用程序/流程应与(为了更好的隔离)连接,注意创建的用户不是超级用户,它不能创建数据库或角色的用户:

createuser --host=rds.example.com --port=5432 \
  --username=rds_master \
  --no-createdb --no-createrole --no-superuser \
  --login --pwprompt \
  db_test_user
Run Code Online (Sandbox Code Playgroud)

如果没有此下一个grant命令,以下内容createdb将失败:

psql --host=rds.example.com --port=5432 \
  --username=rds_master --dbname=postgres \
  --command="grant db_test_user TO rds_master"
Run Code Online (Sandbox Code Playgroud)

createdb做了它在锡上的说法; 请注意db_test_user角色"拥有"数据库:

createdb --host=rds.example.com --port=5432 \
  --username=rds_master --owner=db_test_user test_db
Run Code Online (Sandbox Code Playgroud)

接下来是create schema命令.将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"
Run Code Online (Sandbox Code Playgroud)

最后,我们发出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
Run Code Online (Sandbox Code Playgroud)
  • exit-on-error- 因为否则发现出了什么问题涉及太多的滚动和扫描(single-transaction无论如何都隐含了)
  • single-transaction - 如果事情变成梨形,则避免丢弃或重新创建数据库
  • schema- 只做我们关心的架构(也可以提供给原始pg_dump命令)
  • dbname - 确保使用我们创建的数据库
  • no-owner - db_test_user无论如何我们都在连接,所以一切都应由合适的用户拥有


Sho*_*orn 5

对于生产,您最好只获取实例的 RDS 快照并恢复它,这将创建一个全新的 RDS 实例。

在一个几乎是空的数据库上 - 创建快照需要几分钟,另外 5 分钟左右才能创建新的 RDS 实例(这就是为什么在开发过程中很痛苦的部分原因)。

仅当新 RDS 实例运行时,您才需要为新 RDS 实例付费。保持免费套餐是我想为开发目的使用相同实例创建此数据库的原因之一,而且不必处理第二个 DNS 名称;当您开始拥有多个环境时,这种效果会成倍增加。

运行第二个 RDS 实例是生产的更好选择,因为您几乎完全消除了对原始数据库的任何风险。此外,当您处理大量数据时 - 快照/数据库创建时间将与读取/写入数据所花费的时间相形见绌。对于大量数据,Amazon RDS 快照创建/恢复过程可能比在某个地方的单个服务器上运行的一组脚本具有更好的并行化。此外,RDS 控制台可让您了解恢复的进度——随着数据集的增长和更多的人参与,这变得非常宝贵。