Point-in-Time Restore (PITR)
rabbitmq-backup supports point-in-time restore, allowing you to restore only messages that were backed up within a specific time window. This is useful for recovering from incidents where you need to replay a precise subset of messages.
How It Works
Each backed-up message includes a backed_up_at timestamp (epoch milliseconds). During restore, the tool filters messages based on the time_window_start and time_window_end fields in the restore configuration. Only messages whose timestamps fall within the window are published to the target broker.
Step 1: Identify the Time Window
First, describe the backup to see the time range of available messages:
rabbitmq-backup describe --path s3://rabbitmq-backups --backup-id prod-backup-001 --format json
The output includes per-queue timestamps:
{
"backup_id": "prod-backup-001",
"queues": [
{
"name": "orders-queue",
"vhost": "/",
"message_count": 15000,
"first_message_timestamp": 1705276800000,
"last_message_timestamp": 1705363199000
}
]
}
Convert epoch milliseconds to a readable date to confirm the range:
# Unix timestamp to date
date -d @1705276800 # 2024-01-15 00:00:00 UTC
date -d @1705363199 # 2024-01-15 23:59:59 UTC
Step 2: Configure the Restore
Set time_window_start and time_window_end as epoch milliseconds:
mode: restore
backup_id: "prod-backup-001"
target:
amqp_url: "amqp://guest:guest@localhost:5672/%2f"
management_url: "http://localhost:15672"
management_username: guest
management_password: guest
storage:
backend: s3
bucket: rabbitmq-backups
region: us-east-1
prefix: prod/
restore:
# Restore messages from 10:00 to 11:00 UTC on 2024-01-15
time_window_start: 1705312800000 # 2024-01-15T10:00:00Z
time_window_end: 1705316400000 # 2024-01-15T11:00:00Z
restore_definitions: false # Skip definitions for PITR
publish_mode: exchange
publisher_confirms: true
max_concurrent_queues: 4
produce_batch_size: 100
You can set only time_window_start (restore everything from that point onward) or only time_window_end (restore everything up to that point). Both are optional.
Step 3: Dry Run
Verify which messages would be restored without actually publishing them:
restore:
time_window_start: 1705312800000
time_window_end: 1705316400000
dry_run: true
rabbitmq-backup restore -v --config restore-pitr.yaml
The output shows how many messages match the filter per queue:
INFO Dry run: would restore 423 of 15,000 messages from orders-queue
INFO Dry run: would restore 89 of 3,200 messages from payments-queue
INFO Dry run complete: 512 messages matched the time window
Step 4: Execute the Restore
Set dry_run: false (or remove it) and run:
rabbitmq-backup restore --config restore-pitr.yaml
Step 5: Verify
Check the target queue message counts via the Management UI or API:
curl -u guest:guest http://localhost:15672/api/queues/%2f/orders-queue | jq '.messages'
Generating Epoch Timestamps
Use these commands to convert human-readable times to epoch milliseconds:
# GNU date (Linux)
date -d "2024-01-15T10:00:00Z" +%s%3N
# BSD date (macOS)
date -j -f "%Y-%m-%dT%H:%M:%SZ" "2024-01-15T10:00:00Z" +%s000
# Python (cross-platform)
python3 -c "from datetime import datetime; print(int(datetime(2024,1,15,10,0,0).timestamp() * 1000))"
Combining PITR with Queue Mapping
You can combine time-window filtering with queue remapping to restore filtered messages to different queues:
restore:
time_window_start: 1705312800000
time_window_end: 1705316400000
queue_mapping:
orders-queue: orders-queue-replay
payments-queue: payments-queue-replay
This restores only the messages from the specified time window and publishes them to the -replay queues, leaving the original queues untouched.
Common Scenarios
| Scenario | Configuration |
|---|---|
| Restore everything after an incident | time_window_start only |
| Restore messages lost during a window | Both time_window_start and time_window_end |
| Restore to a point before corruption | time_window_end only |
| Replay to a separate queue | Combine with queue_mapping |
| Inspect without modifying anything | Set dry_run: true |