Surviving the Storm: Disaster Recovery in the Post-Schrems II Era
The rules of engagement changed last month. On July 16, 2020, the CJEU invalidated the Privacy Shield framework in the Schrems II ruling. If you are a CTO or Lead Architect in Europe, your Disaster Recovery (DR) plan relying on replicating encrypted blobs to US-owned object storage buckets might now be legally toxic. We aren't just battling downtime anymore; we are battling non-compliance.
Disaster recovery is often treated as an insurance policy you buy and forget. That is a fatal error. In my fifteen years architecting systems across the Nordics, I have seen more data lost to corrupted restoration processes than to actual hardware failures. A backup you haven't restored is just a file taking up space.
This guide cuts through the noise. We will look at building a DR strategy that satisfies both the Datatilsynet (Norwegian Data Protection Authority) and your need for sub-minute RTO (Recovery Time Objective).
The Physics of Recovery: Bandwidth vs. IOPS
Most VPS providers sell you on CPU cores. But when disaster strikes and you need to rehydrate 500GB of data from a cold backup, CPU is irrelevant. Storage I/O is the bottleneck.
If you are restoring to a standard SATA SSD VPS, you are likely capped at 500 MB/s sequential write speeds, dropping significantly for random writes (like database files). On CoolVDS NVMe instances, we see sustained write speeds effectively saturating the network link. This turns a 4-hour outage into a 15-minute hiccup. High IOPS isn't just for performance; it's your insurance for fast recovery.
Phase 1: Immutable Offsite Backups with Borg
Stop using simple `tar` scripts. They waste space and bandwidth. In 2020, the gold standard for efficient, encrypted backups on Linux is BorgBackup. It offers deduplication, compression, and authenticated encryption.
Here is how we set up a secure, push-based backup from a production server to a secondary storage node (ideally in a different CoolVDS datacenter zone for failure isolation).
1. Initialize the Repository
Run this on your backup server or storage instance:
# On the backup destination
$ borg init --encryption=repokey user@backup-server:backup.borgNote: Save your passphrase in a password manager. If you lose it, the data is cryptographically unrecoverable.
2. The Backup Script
Do not run this manually. Place this in a script managed by Cron or Systemd timers. We use `zstd` compression (available in Borg 1.1+) because it offers the best ratio/speed balance for NVMe storage.
#!/bin/bash
# Configuration
REPOSITORY="user@backup-server:backup.borg"
ARCHIVE_NAME="web-01-$(date +%Y-%m-%d-%H%M)"
# Environment variables for passphrases
export BORG_PASSPHRASE='YourSecurePassphraseHere'
# Execute Backup
borg create \
--verbose \
--filter AME \
--list \
--stats \
--show-rc \
--compression zstd,3 \
--exclude-caches \
$REPOSITORY::$ARCHIVE_NAME \
/etc \
/home \
/var/www \
/var/lib/docker/volumes
# Prune old backups (Keep 7 daily, 4 weekly, 6 monthly)
borg prune \
--list \
--prefix '{hostname}-' \
--show-rc \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
$REPOSITORYPro Tip: Never backup the raw `/var/lib/mysql` directory while the database is running. It leads to corrupted InnoDB tablespaces. Always use `mysqldump` or Percona XtraBackup to stream a consistent state to a file, then have Borg back that up.
Phase 2: Hot Database Replication
Backups cover your RPO (Recovery Point Objective) for catastrophic failure, usually 24 hours. But for business continuity, you need near-zero data loss. MySQL 8.0 (current stable) makes GTID-based replication robust enough for production without third-party tools.
Here is the critical configuration for a Master-Replica setup ensuring strong consistency. This goes in your `my.cnf`:
[mysqld]
# Unique ID for the server (1 for master, 2 for replica)
server-id = 1
# Enable Binary Logging
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
# GTID ensures transactions are tracked uniquely across the cluster
gtid_mode = ON
enforce_gtid_consistency = ON
# Durability settings (Critical for data safety)
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1Setting `sync_binlog = 1` forces a disk sync for every transaction. On spinning rust, this kills performance. On CoolVDS NVMe storage, the latency penalty is negligible, giving you ACID compliance without the slowdown.
Phase 3: The Recovery Playbook
When the primary region goes dark, you don't want to be SSHing into servers and typing commands. You need automation. While tools like Terraform (v0.12+) are excellent for provisioning, Ansible is often superior for the configuration drift that happens during DR.
Below is a simplified Ansible playbook structure to promote a replica to master. This assumes you have already provisioned a standby node on CoolVDS.
---
- name: Promote Slave to Master
hosts: db_replica
become: true
tasks:
- name: Stop Slave Replication
mysql_replication:
mode: stopslave
login_user: root
login_password: "{{ mysql_root_pass }}"
- name: Reset Master to clear slave configuration
command: mysql -u root -p"{{ mysql_root_pass }}" -e "RESET MASTER;"
- name: Update App Configuration to point to new DB
lineinfile:
path: /var/www/html/config.php
regexp: '^DB_HOST'
line: "define('DB_HOST', '{{ inventory_hostname }}');"
delegate_to: web_serverData Sovereignty and Latency
With Schrems II, simply encrypting data before sending it to a US cloud provider (like AWS S3) is no longer a guaranteed safe harbor. The court ruled that US surveillance laws (FISA 702) trump contractual clauses. The safest legal strategy is to keep data resident within the EEA/Norway.
Hosting your DR site in Norway offers two distinct advantages:
- Legal Clarity: Your data stays under Norwegian and European jurisdiction.
- Latency: If your primary market is Oslo or Northern Europe, a failover to a US-East region introduces 90ms+ latency, degrading user experience. Failover to a secondary CoolVDS availability zone keeps latency sub-5ms.
| Metric | US Cloud Cold Storage | CoolVDS NVMe VPS |
|---|---|---|
| Restore Speed (100GB) | ~45-60 Minutes | ~8-12 Minutes |
| Legal Risk (Schrems II) | High | None (EEA Native) |
| Egress Costs | High ($0.09/GB) | Included/Low |
Final Thoughts: Test or Fail
A Disaster Recovery plan is a hypothesis until it is tested. I recommend a "Game Day" once a quarter: deliberately sever the connection to your primary database and measure exactly how long it takes your team to switch to the replica.
If your current hosting provider makes this difficult—either through slow I/O, restrictive networks, or opaque pricing—it is time to reconsider the foundation. CoolVDS is built for the pragmatic engineer: raw KVM performance, NVMe standard, and strict adherence to Norwegian privacy standards.
Don't wait for the subpoena or the crash. Spin up a redundant CoolVDS instance today and secure your infrastructure against both legal and technical failure.