Amazon RDS provides automated daily snapshots by default, but many production environments require more frequent backups. When dealing with critical transactional data, hourly snapshots can be the difference between losing minutes versus hours of data during recovery scenarios.
While RDS doesn't offer native hourly snapshots, we can implement this using AWS services:
# AWS CLI command to manually create snapshot
aws rds create-db-snapshot \
--db-instance-identifier my-database \
--db-snapshot-identifier "hourly-snap-$(date +%Y%m%d-%H%M)"
Here's a complete solution using AWS Lambda triggered by CloudWatch Events:
import boto3
import time
def lambda_handler(event, context):
rds = boto3.client('rds')
timestamp = time.strftime('%Y%m%d-%H%M')
response = rds.create_db_snapshot(
DBInstanceIdentifier='my-database',
DBSnapshotIdentifier=f'hourly-snap-{timestamp}',
Tags=[
{
'Key': 'BackupType',
'Value': 'AutomatedHourly'
},
]
)
return {
'statusCode': 200,
'body': response
}
For infrastructure-as-code deployment:
AWSTemplateFormatVersion: '2010-09-09'
Resources:
HourlySnapshotLambda:
Type: AWS::Lambda::Function
Properties:
Handler: index.lambda_handler
Role: !GetAtt LambdaExecutionRole.Arn
Runtime: python3.8
Code:
ZipFile: |
# Paste the Python code above here
SnapshotScheduleRule:
Type: AWS::Events::Rule
Properties:
ScheduleExpression: "rate(1 hour)"
Targets:
- Arn: !GetAtt HourlySnapshotLambda.Arn
Id: "HourlyRDSSnapshot"
Add this to your Lambda function to maintain 24 hourly snapshots:
def cleanup_old_snapshots():
rds = boto3.client('rds')
snapshots = rds.describe_db_snapshots(
DBInstanceIdentifier='my-database',
SnapshotType='manual'
)['DBSnapshots']
# Sort by creation time (ascending)
snapshots.sort(key=lambda x: x['SnapshotCreateTime'])
# Keep last 24 snapshots
if len(snapshots) > 24:
for snapshot in snapshots[:-24]:
rds.delete_db_snapshot(
DBSnapshotIdentifier=snapshot['DBSnapshotIdentifier']
)
- Snapshot creation is asynchronous and may take several minutes
- Frequent snapshots may impact performance during creation
- Monitor your storage costs as each snapshot stores only changed blocks
- Consider implementing in a DR region for additional protection
Amazon RDS provides two primary backup methods: automated system snapshots and manual DB snapshots. While automated backups occur daily during your preferred backup window, they don't natively support hourly increments. Here's how we can implement an hourly solution.
We'll combine AWS services to create an automated hourly backup system:
- RDS automated backups (daily)
- AWS Lambda for triggering snapshots
- CloudWatch Events for scheduling
- S3 for long-term storage
Create a Python Lambda function that triggers RDS snapshots:
import boto3
from datetime import datetime
def lambda_handler(event, context):
rds = boto3.client('rds')
db_instance = 'your-db-instance-identifier'
timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M")
snapshot_id = f"{db_instance}-hourly-{timestamp}"
response = rds.create_db_snapshot(
DBSnapshotIdentifier=snapshot_id,
DBInstanceIdentifier=db_instance,
Tags=[
{
'Key': 'BackupType',
'Value': 'Hourly'
},
]
)
return response
Set up a CloudWatch rule to trigger the Lambda hourly:
{
"detail-type": [
"Scheduled Event"
],
"source": [
"aws.events"
],
"detail": {},
"schedule": "rate(1 hour)"
}
To prevent excessive storage costs, implement a cleanup script:
import boto3
from datetime import datetime, timedelta
def cleanup_old_snapshots():
rds = boto3.client('rds')
retention_days = 7
cutoff_time = datetime.now() - timedelta(days=retention_days)
snapshots = rds.describe_db_snapshots(
SnapshotType='manual',
Filters=[{'Name': 'tag:BackupType', 'Values': ['Hourly']}]
)
for snapshot in snapshots['DBSnapshots']:
snapshot_time = snapshot['SnapshotCreateTime'].replace(tzinfo=None)
if snapshot_time < cutoff_time:
rds.delete_db_snapshot(
DBSnapshotIdentifier=snapshot['DBSnapshotIdentifier']
)
For more granular control, consider periodic database dumps to S3:
mysqldump -h your-rds-endpoint -u user -p database_name | gzip | aws s3 cp - s3://your-bucket/hourly-backups/backup-$(date +%Y%m%d%H%M%S).sql.gz
Set up CloudWatch alarms to monitor backup success/failure:
aws cloudwatch put-metric-alarm \
--alarm-name "RDS-Hourly-Backup-Failure" \
--metric-name "Errors" \
--namespace "AWS/Lambda" \
--statistic "Sum" \
--period 3600 \
--threshold 1 \
--comparison-operator "GreaterThanOrEqualToThreshold" \
--evaluation-periods 1 \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:Backup-Alerts" \
--dimensions Name=FunctionName,Value=YourLambdaFunctionName
Remember that each manual snapshot incurs storage costs. For a high-frequency backup strategy:
- Evaluate your actual RPO (Recovery Point Objective) needs
- Consider using Aurora with its continuous backup capability
- Implement lifecycle policies to move older backups to cheaper storage classes