Pick the path
| Situation | Fastest recovery |
|---|---|
| Bad UPDATE/DELETE, Aurora MySQL with Backtrack enabled | Backtrack the cluster (minutes, in place) |
| Bad change, instance still exists | Point-in-time restore to a new instance |
| Instance deleted, automated backups retained | Restore from retained backups |
| Instance deleted with final snapshot | Restore from snapshot |
| Deleted, no retained backups, no snapshot | AWS Backup copies or other-account snapshots only |
All RDS restores create a new instance or cluster.
1. Point-in-time restore (RDS)
aws rds describe-db-instances --db-instance-identifier orders-prod \
--query "DBInstances[0].LatestRestorableTime"
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier orders-prod \
--target-db-instance-identifier orders-prod-pitr \
--restore-time 2026-10-24T07:30:00Z \
--db-subnet-group-name prod-db-subnets \
--vpc-security-group-ids sg-0123456789abcdef0 \
--no-publicly-accessible
Set the parameter group, option group, instance class and Multi-AZ explicitly to match production — defaults may differ.
2. Aurora point-in-time and Backtrack
aws rds restore-db-cluster-to-point-in-time \
--source-db-cluster-identifier orders-aurora --db-cluster-identifier orders-aurora-pitr \
--restore-to-time 2026-10-24T07:30:00Z --db-subnet-group-name prod-db-subnets
aws rds create-db-instance --db-cluster-identifier orders-aurora-pitr \
--db-instance-identifier orders-aurora-pitr-1 --db-instance-class db.r6g.large --engine aurora-postgresql
A restored Aurora cluster has no instances until you add one.
Backtrack (Aurora MySQL only, if enabled when the cluster was created or restored):
aws rds backtrack-db-cluster --db-cluster-identifier orders-aurora-mysql --backtrack-to 2026-10-24T07:30:00Z
Warning
Backtrack rewinds the whole cluster in place, including good writes after that time. Stop writes first and agree it with the app owner.
3. Deleted instance
aws rds describe-db-instance-automated-backups --db-instance-identifier orders-prod
aws rds restore-db-instance-to-point-in-time \
--source-dbi-resource-id db-ABCDEFGHIJKLMNOP \
--target-db-instance-identifier orders-prod \
--use-latest-restorable-time
From a final or manual snapshot:
aws rds describe-db-snapshots --db-instance-identifier orders-prod --snapshot-type manual
aws rds restore-db-instance-from-db-snapshot --db-instance-identifier orders-prod \
--db-snapshot-identifier orders-prod-final --db-subnet-group-name prod-db-subnets
4. Put it back in service
- Partial fix: copy the damaged rows from the restored copy into production with
pg_dump -t,mysqldump --whereor a script, inside a reviewed transaction. - Full swap: rename instances (
modify-db-instance --new-db-instance-identifier) so the endpoint name matches the old one, or update a Route 53 CNAME that apps use.
aws rds modify-db-instance --db-instance-identifier orders-prod --new-db-instance-identifier orders-prod-broken --apply-immediately
aws rds modify-db-instance --db-instance-identifier orders-prod-pitr --new-db-instance-identifier orders-prod --apply-immediately
Re-check: Multi-AZ, backups retention, Performance Insights, enhanced monitoring, IAM auth, read replicas (re-create), event subscriptions.
Prevent it next time
DeletionProtection=trueon every production instance and cluster.- Retain automated backups on deletion; keep a final snapshot.
- Copy snapshots to a separate backup account with AWS Backup vault lock.
- Enable Backtrack on Aurora MySQL clusters where fast undo matters.