从 RDS 快照恢复订单

AWSBeginner
立即练习

介绍

意外的数据修改可能让订单应用继续运行,却丢失业务记录。你将创建手动 RDS 快照,执行受控删除,然后通过恢复新数据库实例并切换应用端点找回丢失订单。

请先完成前面的数据库和 SQL 实验。本独立环境提供包含三笔示例订单的主数据库及已连接的应用。证明恢复成功后,你将删除两个练习实例和快照。

认证考试关联

本实验为以下考试主题提供入门实践。

创建手动数据库快照

本步骤在修改数据之前保存当前数据库数据。

DB 快照是 RDS 数据库实例的恢复副本。手动快照由显式操作创建,并作为独立资源保留,直到被删除。本实验使用一个手动快照,不配置自动备份保留或时间点恢复。

加载准备好的连接设置,并检查应用数据:

cd /home/labex/project
source database.env
curl \
  --silent \
  --show-error \
  --fail \
  http://127.0.0.1:8080/application/orders | jq

应看到订单 101、102 和 103。订单 101 属于 Maya,金额为 49.90。

创建数据库快照:

aws rds \
  create-db-snapshot \
  --db-instance-identifier orders-db \
  --db-snapshot-identifier orders-before-delete \
  --query 'DBSnapshot.{Snapshot:DBSnapshotIdentifier,Source:DBInstanceIdentifier,Status:Status}'
aws rds \
  wait db-snapshot-available \
  --db-snapshot-identifier orders-before-delete
aws rds \
  describe-db-snapshots \
  --db-snapshot-identifier orders-before-delete \
  --query 'DBSnapshots[].{Snapshot:DBSnapshotIdentifier,Type:SnapshotType,Source:DBInstanceIdentifier,Status:Status}'

应看到 orders-db 的手动快照,状态为 available。AWS View 应在主数据库旁显示新快照。等待快照完成后再进行下一项修改。

观察受控的数据丢失

本步骤仅删除一笔示例订单,并观察应用数据变化。

以下删除是本练习中的有意操作。WHERE 子句将范围限制为订单 101:

psql \
  "service=orders-db" \
  --set=ON_ERROR_STOP=1 \
  --command 'DELETE FROM orders WHERE order_id = 101;'

读取剩余数据行:

psql \
  "service=orders-db" \
  --command 'SELECT order_id, customer, total FROM orders ORDER BY order_id;'

应仅看到订单 102 和 103。请求应用列表:

curl \
  --silent \
  --show-error \
  --fail \
  http://127.0.0.1:8080/application/orders | jq

应用仍然可以连接和响应,但 Maya 的订单已丢失。连接正常不能证明业务数据完整。删除前的快照包含所需的恢复副本。

恢复新实例并切换应用

本步骤将快照恢复到新实例,并证明应用读取其恢复数据。

恢复产生新端点;虚线对比未被回滚的源实例

概念图:恢复产生新端点;虚线对比未被回滚的源实例。

快照恢复会创建一个新 RDS 实例,不会原地回退现有实例。使用不同标识符,并明确选择准备好的子网组和安全组:

aws rds \
  restore-db-instance-from-db-snapshot \
  --db-instance-identifier orders-restored \
  --db-snapshot-identifier orders-before-delete \
  --db-instance-class db.t3.micro \
  --db-subnet-group-name orders-subnets \
  --vpc-security-group-ids "$DB_SECURITY_GROUP_ID" \
  --no-publicly-accessible \
  --query 'DBInstance.{Identifier:DBInstanceIdentifier,Status:DBInstanceStatus,Endpoint:Endpoint}'
aws rds \
  wait db-instance-available \
  --db-instance-identifier orders-restored

通过准备好的连接条目查询新引擎:

psql \
  "service=orders-restored" \
  --command 'SELECT order_id, customer, total FROM orders ORDER BY order_id;'

应看到全部三笔原始订单。独立检查来源数据库:

psql \
  "service=orders-db" \
  --command 'SELECT order_id, customer, total FROM orders ORDER BY order_id;'

来源仍应仅包含 102 和 103。现在有两个独立实例:修改后的来源和恢复的数据库。

获取恢复数据库端点,并更新应用的两个主机字段:

RESTORED_ENDPOINT=$(aws rds \
  describe-db-instances \
  --db-instance-identifier orders-restored \
  --query 'DBInstances[0].Endpoint.Address' \
  --output text)
jq \
  --arg host "$RESTORED_ENDPOINT" \
  '.read_host = $host | .write_host = $host' \
  app-config.json > app-config.new
mv app-config.new app-config.json

测试应用:

curl \
  --silent \
  --show-error \
  --fail \
  http://127.0.0.1:8080/application/orders | jq

应再次看到订单 101、102 和 103。AWS View 应列出两个实例,并显示恢复后的订单数据。只有应用使用恢复端点且预期记录可用,才算恢复完成,而不仅仅是创建了实例。

快照包含删除之前保存的数据。备份后的修改不会自动出现在恢复实例中。备份时机和应用切换决策对于恢复规划很重要。 应用从独立恢复的 PostgreSQL 实例读取找回的订单。

删除两个实例及手动快照

本步骤删除使用过的所有恢复资源。

删除恢复实例和原始练习实例:

aws rds \
  delete-db-instance \
  --db-instance-identifier orders-restored \
  --skip-final-snapshot \
  --query 'DBInstance.DBInstanceIdentifier'
aws rds \
  delete-db-instance \
  --db-instance-identifier orders-db \
  --skip-final-snapshot \
  --query 'DBInstance.DBInstanceIdentifier'
aws rds \
  wait db-instance-deleted \
  --db-instance-identifier orders-restored
aws rds \
  wait db-instance-deleted \
  --db-instance-identifier orders-db

手动快照与实例相互独立,也必须删除:

aws rds \
  delete-db-snapshot \
  --db-snapshot-identifier orders-before-delete \
  --query 'DBSnapshot.DBSnapshotIdentifier'

检查两个资源列表:

aws rds \
  describe-db-instances \
  --query 'DBInstances[].DBInstanceIdentifier'
aws rds \
  describe-db-snapshots \
  --snapshot-type manual \
  --query 'DBSnapshots[].DBSnapshotIdentifier'

两者都应显示 []。AWS View 不应显示数据库或手动快照。保留准备好的应用和网络。

总结

你创建了手动数据库快照,观察了受控删除,并将保存的数据恢复到新实例。切换应用端点找回了丢失订单,同时来源保持不变。随后你删除了两个实例和独立的手动快照。

下一项实验使用 PostgreSQL 只读副本分离应用的读写请求。