Disaster Recovery in the Age of GDPR: Why Your "Backup" Is a Liability
Today is May 25, 2018. The grace period is over. The General Data Protection Regulation (GDPR) is now fully enforceable across the EEA. If you are a SysAdmin operating in Norway or serving EU customers, your job description just changed. It is no longer enough to simply "have backups."
If your Disaster Recovery (DR) plan involves dumping unencrypted SQL files to an AWS bucket in Virginia, you are non-compliant. If your recovery time takes 12 hours because you are restoring to a spinning-disk VPS, you are losing money. I have spent the last week auditing infrastructure for a major Oslo-based e-commerce retailer, and the state of "professional" DR plans is terrifying. Most are just scripts waiting to fail.
Let’s cut the fluff. Here is how to architect a DR strategy that satisfies both the Datatilsynet and your uptime SLAs, using tools available right now in 2018.
The RTO/RPO Reality Check
Before we touch a single line of code, define your metrics. In a catastrophic failure (e.g., `rm -rf /var/lib/mysql` or a datacenter power outage), you have two variables:
- RPO (Recovery Point Objective): How much data can you lose? (e.g., "1 hour")
- RTO (Recovery Time Objective): How long until the site is back online? (e.g., "15 minutes")
The bottleneck for RTO is almost always Disk I/O. I recently watched a developer try to restore a 40GB MySQL dump on a standard "cloud" instance from a generic provider. It took 6 hours. The disk wait times were astronomical because the provider was overselling their storage arrays.
This is why we reference CoolVDS implementations for mission-critical workloads. Their use of NVMe storage (Non-Volatile Memory Express) isn't just a marketing buzzword; it effectively eliminates the I/O bottleneck during the `mysql < dump.sql` import process. If your host is still running SATA SSDs over a choked network fabric, your DR plan is theoretically flawed.
Pro Tip: Don't guess your disk speed. Test it. Before deploying your production DB, run `fio` to simulate a restore load.
# Install fio on Ubuntu 18.04
apt-get update && apt-get install -y fio
# Simulate a database restore workload (Random Write/Read mix)
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 \
--name=test --filename=test --bs=4k --iodepth=64 --size=1G \
--readwrite=randrw --rwmixread=75
On a proper NVMe KVM slice (like CoolVDS), you should see IOPS in the tens of thousands. If you see IOPS under 500, move your data immediately.
The "Norway Problem": Sovereignty and Latency
Under GDPR, transferring personal data outside the EEA requires strict legal frameworks (like Privacy Shield, which is already under heavy scrutiny). The safest technical implementation is Data Sovereignty: Keep the data in Norway.
Hosting your primary node in Oslo isn't just about compliance; it's about physics. The latency from the Norwegian Internet Exchange (NIX) to a server in Oslo is 1-3ms. To Frankfurt, it's 20-30ms. For a high-transaction database, that round-trip time adds up.
Your offsite backup must also be compliant. Encrypting your backups before they leave the server is mandatory. Do not rely on "encryption at rest" provided by the storage vendor. You need to control the keys.
Step 1: The Automated, Encrypted Backup
Forget manual snapshots. We need an automated bash script that dumps the database, encrypts it with GPG, and ships it offsite. We will use `mysqldump` with `single-transaction` to avoid locking InnoDB tables during the backup.
Here is the script I use for production workloads on Ubuntu 16.04/18.04:
#!/bin/bash
# CONFIGURATION
DB_USER="root"
DB_PASS="SuperSecretPassword123"
DB_NAME="production_db"
BACKUP_DIR="/var/backups/sql"
DATE=$(date +%Y-%m-%d_%H%M%S)
GPG_RECIPIENT="admin@yourcompany.no"
# 1. Create Backup Directory
mkdir -p $BACKUP_DIR
chmod 700 $BACKUP_DIR
# 2. Dump and Compress
# Note: --single-transaction is critical for live InnoDB tables
echo "Starting dump..."
mysqldump -u $DB_USER -p$DB_PASS --single-transaction --quick --lock-tables=false $DB_NAME | gzip > $BACKUP_DIR/$DB_NAME-$DATE.sql.gz
# 3. Encrypt for GDPR Compliance
# You must import your public key via 'gpg --import public.key' first
echo "Encrypting..."
gpg --yes --batch --trust-model always -r $GPG_RECIPIENT -e $BACKUP_DIR/$DB_NAME-$DATE.sql.gz
# 4. Remove the unencrypted gzip file immediately
rm $BACKUP_DIR/$DB_NAME-$DATE.sql.gz
# 5. Offsite Transfer (Example using Rsync)
# Ensure SSH keys are set up between hosts
rsync -avz -e "ssh -p 22" $BACKUP_DIR/$DB_NAME-$DATE.sql.gz.gpg user@backup-server.coolvds.net:/home/backup/
# 6. Cleanup old local backups (Keep 7 days)
find $BACKUP_DIR -type f -name "*.gpg" -mtime +7 -exec rm {} \;
echo "Backup Complete: $DB_NAME-$DATE.sql.gz.gpg"
Key Configuration Details:
--single-transaction: Ensures data consistency without stopping your web application.gpg ... -e: Encrypts the file so that even if your backup server is compromised, the data is unreadable without your private key. This is a "Get Out of Jail Free" card for GDPR breach notifications.
Step 2: Infrastructure as Code (Ansible)
A backup file is useless if you don't have a server to put it on. In 2018, manually installing Nginx and PHP is negligence. Use Ansible.
If your primary server in the Oslo datacenter goes dark, you need to spin up a fresh CoolVDS instance and provision it in minutes. Below is a snippet of an Ansible playbook that configures the Nginx environment for recovery.
---
- hosts: recovery_nodes
become: yes
vars:
http_port: 80
server_name: www.example.no
tasks:
- name: Install Nginx and MySQL Client
apt:
name: ["nginx", "mysql-client", "python3-pymysql"]
state: present
update_cache: yes
- name: Remove default Nginx config
file:
path: /etc/nginx/sites-enabled/default
state: absent
- name: Deploy DR Vhost Configuration
template:
src: templates/dr_vhost.j2
dest: /etc/nginx/sites-available/dr_site
notify: Restart Nginx
- name: Enable DR Site
file:
src: /etc/nginx/sites-available/dr_site
dest: /etc/nginx/sites-enabled/dr_site
state: link
handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted
By keeping this playbook in a private Git repository, you can turn a fresh OS install into a production-ready web server in roughly 4 minutes.
Step 3: Handling the Maintenance Window
While your database restores, you cannot show users a generic "502 Bad Gateway". It looks unprofessional and destroys trust. Configure Nginx to serve a static "Maintenance" page that returns a 503 status code (Service Unavailable). This tells Google bots to come back later rather than de-indexing your site.
Nginx Configuration Snippet:
server {
listen 80;
server_name example.no;
root /var/www/html;
index index.html;
# Redirect all traffic to maintenance.html if the file exists
if (-f $document_root/maintenance.html) {
return 503;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.html break;
}
}
Why Hardware Matters (The KVM Advantage)
When disaster strikes, you are likely not the only one. If the outage is regional, thousands of admins are scrambling to restore backups simultaneously. On shared hosting or container-based virtualization (like OpenVZ), this creates a "noisy neighbor" effect where CPU stealing slows your recovery to a crawl.
This is where the architecture of CoolVDS becomes a strategic asset. We utilize KVM (Kernel-based Virtual Machine). This means your RAM and CPU resources are hard-allocated. Your kernel is your own. Even if the neighbor on the physical host is compiling a kernel, your `gunzip` process gets the CPU cycles it needs to decrypt your backup fast.
Conclusion: Don't Wait for the Fire
The regulations have changed, and the bar for technical competence has been raised. A GDPR fine can be up to €20 million, but the loss of customer trust from a 24-hour outage is incalculable.
Review your scripts today. Generate a GPG key pair. And ensure your infrastructure runs on hardware that respects your need for speed and sovereignty.
Next Step: Don't let slow I/O kill your recovery time. Deploy a KVM-based, NVMe-powered test instance on CoolVDS in Oslo today. Measure the difference yourself.