Related: For zero-downtime engine upgrades and schema changes, see RDS-BlueGreen-General.md.
1. Overview
What is RDS Multi-AZ?
- Synchronous replication to standby instance in different AZ
- Automatic failover for high availability
- Zero data loss during planned maintenance or failures
- Enhanced durability and availability for production databases
Key Benefits
- High Availability - Automatic failover within 60-120 seconds
- Data Durability - Synchronous replication prevents data loss
- Maintenance - Zero-downtime maintenance operations
- Backup - Backups taken from standby to reduce I/O impact
2. Multi-AZ Deployment Types
Multi-AZ DB Instance
# Create Multi-AZ RDS instance
aws rds create-db-instance \
--db-instance-identifier "prod-database" \
--db-instance-class "db.r5.xlarge" \
--engine "mysql" \
--engine-version "8.0.35" \
--master-username "admin" \
--master-user-password "SecurePassword123!" \
--allocated-storage 100 \
--storage-type "gp3" \
--storage-encrypted \
--multi-az \
--vpc-security-group-ids "sg-12345678" \
--db-subnet-group-name "prod-subnet-group" \
--backup-retention-period 7 \
--preferred-backup-window "03:00-04:00" \
--preferred-maintenance-window "sun:04:00-sun:05:00"Multi-AZ DB Cluster
# Create Multi-AZ Aurora cluster
aws rds create-db-cluster \
--db-cluster-identifier "prod-aurora-cluster" \
--engine "aurora-mysql" \
--engine-version "8.0.mysql_aurora.3.02.0" \
--master-username "admin" \
--master-user-password "SecurePassword123!" \
--vpc-security-group-ids "sg-12345678" \
--db-subnet-group-name "aurora-subnet-group" \
--backup-retention-period 7 \
--storage-encrypted \
--enable-cloudwatch-logs-exports "error,general,slowquery"
# Add cluster instances
aws rds create-db-instance \
--db-instance-identifier "prod-aurora-writer" \
--db-instance-class "db.r5.large" \
--engine "aurora-mysql" \
--db-cluster-identifier "prod-aurora-cluster"
aws rds create-db-instance \
--db-instance-identifier "prod-aurora-reader" \
--db-instance-class "db.r5.large" \
--engine "aurora-mysql" \
--db-cluster-identifier "prod-aurora-cluster"3. Failover Mechanisms
Automatic Failover Scenarios
- Primary DB instance failure
- Availability Zone outage
- Network connectivity loss
- Storage failure
Failover Process
def monitor_rds_failover():
"""Monitor RDS failover events"""
rds = boto3.client('rds')
# Describe DB instances to check status
response = rds.describe_db_instances(
DBInstanceIdentifier='prod-database'
)
db_instance = response['DBInstances'][0]
# Check Multi-AZ status
multi_az_status = db_instance['MultiAZ']
db_status = db_instance['DBInstanceStatus']
if db_status == 'failed-over':
# Handle post-failover actions
handle_post_failover_actions(db_instance)
return {
'multi_az': multi_az_status,
'status': db_status,
'endpoint': db_instance['Endpoint']['Address']
}
def handle_post_failover_actions(db_instance):
"""Handle actions after RDS failover"""
# Update application configuration if needed
update_connection_strings(db_instance['Endpoint']['Address'])
# Send notifications
send_failover_notification(db_instance)
# Verify application connectivity
verify_database_connectivity(db_instance)Manual Failover Testing
# Force failover for testing
aws rds reboot-db-instance \
--db-instance-identifier "prod-database" \
--force-failover4. Read Replicas for Scalability
Cross-AZ Read Replicas
# Create read replica in different AZ
aws rds create-db-instance-read-replica \
--db-instance-identifier "prod-database-replica-1" \
--source-db-instance-identifier "prod-database" \
--db-instance-class "db.r5.large" \
--availability-zone "us-east-1b" \
--publicly-accessible false
# Create cross-region read replica
aws rds create-db-instance-read-replica \
--db-instance-identifier "prod-database-replica-west" \
--source-db-instance-identifier "arn:aws:rds:us-east-1:123456789012:db:prod-database" \
--db-instance-class "db.r5.large" \
--region us-west-2Read Replica Monitoring
def monitor_read_replica_lag():
"""Monitor read replica lag"""
cloudwatch = boto3.client('cloudwatch')
# Get replica lag metrics
response = cloudwatch.get_metric_statistics(
Namespace='AWS/RDS',
MetricName='ReplicaLag',
Dimensions=[
{
'Name': 'DBInstanceIdentifier',
'Value': 'prod-database-replica-1'
}
],
StartTime=datetime.utcnow() - timedelta(hours=1),
EndTime=datetime.utcnow(),
Period=300,
Statistics=['Average', 'Maximum']
)
# Check if lag is acceptable
max_lag = max([point['Maximum'] for point in response['Datapoints']])
if max_lag > 30: # 30 seconds threshold
send_lag_alert(max_lag)
return max_lag5. Backup and Recovery Strategies
Automated Backups
def configure_backup_strategy():
"""Configure comprehensive backup strategy"""
rds = boto3.client('rds')
# Modify backup settings
rds.modify_db_instance(
DBInstanceIdentifier='prod-database',
BackupRetentionPeriod=30, # 30 days retention
PreferredBackupWindow='03:00-04:00', # Low traffic window
PreferredMaintenanceWindow='sun:04:00-sun:05:00',
ApplyImmediately=False # Apply during maintenance window
)
# Enable automated backups for read replicas
rds.modify_db_instance(
DBInstanceIdentifier='prod-database-replica-1',
BackupRetentionPeriod=7,
ApplyImmediately=False
)Manual Snapshots
# Create manual snapshot
aws rds create-db-snapshot \
--db-instance-identifier "prod-database" \
--db-snapshot-identifier "prod-database-snapshot-$(date +%Y%m%d%H%M%S)"
# Copy snapshot to another region
aws rds copy-db-snapshot \
--source-db-snapshot-identifier "prod-database-snapshot-20240115120000" \
--target-db-snapshot-identifier "prod-database-snapshot-20240115120000-copy" \
--source-region us-east-1 \
--region us-west-2Point-in-Time Recovery
def perform_point_in_time_recovery():
"""Perform point-in-time recovery"""
rds = boto3.client('rds')
# Restore to specific point in time
response = rds.restore_db_instance_to_point_in_time(
SourceDBInstanceIdentifier='prod-database',
TargetDBInstanceIdentifier='prod-database-restored',
RestoreTime=datetime(2024, 1, 15, 10, 30, 0), # UTC time
DBInstanceClass='db.r5.xlarge',
MultiAZ=True,
PubliclyAccessible=False,
VpcSecurityGroupIds=['sg-12345678'],
DBSubnetGroupName='prod-subnet-group'
)
return response6. Performance Monitoring and Optimization
Performance Insights
# Enable Performance Insights
aws rds modify-db-instance \
--db-instance-identifier "prod-database" \
--enable-performance-insights \
--performance-insights-retention-period 7 \
--apply-immediatelyCloudWatch Metrics
def setup_rds_monitoring():
"""Set up comprehensive RDS monitoring"""
cloudwatch = boto3.client('cloudwatch')
# CPU utilization alarm
cloudwatch.put_metric_alarm(
AlarmName='RDS-HighCPU',
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=2,
MetricName='CPUUtilization',
Namespace='AWS/RDS',
Period=300,
Statistic='Average',
Threshold=80.0,
ActionsEnabled=True,
AlarmActions=[
'arn:aws:sns:us-east-1:123456789012:rds-alerts'
],
Dimensions=[
{
'Name': 'DBInstanceIdentifier',
'Value': 'prod-database'
}
]
)
# Database connections alarm
cloudwatch.put_metric_alarm(
AlarmName='RDS-HighConnections',
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=2,
MetricName='DatabaseConnections',
Namespace='AWS/RDS',
Period=300,
Statistic='Average',
Threshold=80,
ActionsEnabled=True,
AlarmActions=[
'arn:aws:sns:us-east-1:123456789012:rds-alerts'
]
)
# Read replica lag alarm
cloudwatch.put_metric_alarm(
AlarmName='RDS-ReplicaLag',
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=1,
MetricName='ReplicaLag',
Namespace='AWS/RDS',
Period=300,
Statistic='Average',
Threshold=30,
ActionsEnabled=True,
AlarmActions=[
'arn:aws:sns:us-east-1:123456789012:rds-alerts'
],
Dimensions=[
{
'Name': 'DBInstanceIdentifier',
'Value': 'prod-database-replica-1'
}
]
)7. Security and Encryption
Encryption at Rest
# Create encrypted RDS instance
aws rds create-db-instance \
--db-instance-identifier "secure-database" \
--db-instance-class "db.r5.large" \
--engine "postgres" \
--master-username "admin" \
--master-user-password "SecurePassword123!" \
--allocated-storage 100 \
--storage-encrypted \
--kms-key-id "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012" \
--multi-azNetwork Security
def configure_rds_security():
"""Configure RDS security settings"""
ec2 = boto3.client('ec2')
# Create security group for RDS
sg_response = ec2.create_security_group(
GroupName='rds-security-group',
Description='Security group for RDS instances',
VpcId='vpc-12345678'
)
security_group_id = sg_response['GroupId']
# Allow access from application servers only
ec2.authorize_security_group_ingress(
GroupId=security_group_id,
IpPermissions=[
{
'IpProtocol': 'tcp',
'FromPort': 3306,
'ToPort': 3306,
'UserIdGroupPairs': [
{
'GroupId': 'sg-app-servers',
'Description': 'MySQL access from app servers'
}
]
}
]
)
return security_group_id8. Disaster Recovery Strategies
Cross-Region Disaster Recovery
def setup_cross_region_dr():
"""Set up cross-region disaster recovery"""
# Primary region setup
primary_rds = boto3.client('rds', region_name='us-east-1')
# Create cross-region read replica
dr_replica = primary_rds.create_db_instance_read_replica(
DBInstanceIdentifier='prod-database-dr',
SourceDBInstanceIdentifier='arn:aws:rds:us-east-1:123456789012:db:prod-database',
DBInstanceClass='db.r5.xlarge',
PubliclyAccessible=False,
MultiAZ=True,
StorageEncrypted=True
)
# Set up automated snapshots in DR region
dr_rds = boto3.client('rds', region_name='us-west-2')
# Configure backup retention for DR replica
dr_rds.modify_db_instance(
DBInstanceIdentifier='prod-database-dr',
BackupRetentionPeriod=30,
PreferredBackupWindow='06:00-07:00', # Different window than primary
ApplyImmediately=False
)
def promote_read_replica_for_dr():
"""Promote read replica during disaster recovery"""
dr_rds = boto3.client('rds', region_name='us-west-2')
# Promote read replica to standalone instance
response = dr_rds.promote_read_replica(
DBInstanceIdentifier='prod-database-dr'
)
# Wait for promotion to complete
waiter = dr_rds.get_waiter('db_instance_available')
waiter.wait(DBInstanceIdentifier='prod-database-dr')
# Update application configuration to use new endpoint
update_application_config_for_dr()
return response9. Cost Optimization
Reserved Instances
def optimize_rds_costs():
"""Implement RDS cost optimization strategies"""
rds = boto3.client('rds')
# Get current instance information
instances = rds.describe_db_instances()
recommendations = []
for instance in instances['DBInstances']:
db_id = instance['DBInstanceIdentifier']
instance_class = instance['DBInstanceClass']
engine = instance['Engine']
# Check utilization metrics
utilization = get_instance_utilization(db_id)
if utilization['cpu_avg'] < 20:
recommendations.append({
'instance': db_id,
'recommendation': 'Consider downsizing',
'current_class': instance_class,
'suggested_class': get_smaller_instance_class(instance_class)
})
# Check for Reserved Instance opportunities
if utilization['consistent_usage']:
recommendations.append({
'instance': db_id,
'recommendation': 'Consider Reserved Instance',
'potential_savings': calculate_ri_savings(instance_class, engine)
})
return recommendationsStorage Optimization
# Convert to gp3 for better performance and cost
aws rds modify-db-instance \
--db-instance-identifier "prod-database" \
--storage-type "gp3" \
--iops 3000 \
--storage-throughput 125 \
--apply-immediately false10. Common Exam Scenarios
Scenario 1: High availability database for critical application
Solution:
- Multi-AZ RDS deployment with automatic failover
- Read replicas for read scaling
- Automated backups with 30-day retention
- Performance Insights for monitoring
Scenario 2: Global application with read scaling
Solution:
- Multi-AZ primary in main region
- Cross-region read replicas for global read access
- Aurora Global Database for ultra-low latency
- Route 53 for intelligent routing
Scenario 3: Disaster recovery with RPO < 1 hour
Solution:
- Multi-AZ deployment for local HA
- Cross-region automated backups
- Read replica in DR region for fast promotion
- Automated failover procedures
Scenario 4: Cost optimization for development environments
Solution:
- Single-AZ instances for non-production
- Scheduled start/stop for development databases
- Smaller instance classes with burstable performance
- Shorter backup retention periods
Scenario 5: Zero-downtime maintenance and upgrades
Solution:
- Multi-AZ deployment for maintenance windows
- Blue/green deployments for major upgrades
- Read replica promotion for version upgrades
- Automated backup before changes
11. CLI Commands Reference
Instance Management
# Create Multi-AZ instance
aws rds create-db-instance \
--db-instance-identifier "my-db" \
--db-instance-class "db.t3.micro" \
--engine "mysql" \
--master-username "admin" \
--master-user-password "password" \
--allocated-storage 20 \
--multi-az
# Modify to enable Multi-AZ
aws rds modify-db-instance \
--db-instance-identifier "my-db" \
--multi-az \
--apply-immediately
# Force failover
aws rds reboot-db-instance \
--db-instance-identifier "my-db" \
--force-failoverBackup and Recovery
# Create snapshot
aws rds create-db-snapshot \
--db-instance-identifier "my-db" \
--db-snapshot-identifier "my-db-snapshot"
# Restore from snapshot
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier "restored-db" \
--db-snapshot-identifier "my-db-snapshot"
# Point-in-time recovery
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier "my-db" \
--target-db-instance-identifier "restored-db" \
--restore-time "2024-01-15T10:30:00.000Z"12. Exam Tips
Key Points to Remember
- Multi-AZ provides high availability, not read scaling
- Failover is automatic and typically takes 60-120 seconds
- Read replicas can be promoted to standalone instances
- Backups are taken from standby instance in Multi-AZ
- Cross-region read replicas provide disaster recovery capability
- Aurora offers better availability and performance than standard RDS
Common Mistakes
- Confusing Multi-AZ with read replicas
- Not configuring proper backup windows
- Forgetting to enable encryption for sensitive data
- Not monitoring replica lag in read replicas
- Overlooking security group configurations
- Not testing failover procedures
Best Practices for Exam
- Understand Multi-AZ vs read replica differences
- Know failover scenarios and timing
- Understand backup and recovery options
- Know monitoring and alerting capabilities
- Understand cost optimization strategies
- Know disaster recovery patterns and procedures