Your app is replaceable; your data isn't. Two layers protect it: backups (recover from mistakes/disasters) and replication (stay available when a server dies). They solve different problems — you usually want both.
Backups — logical dumps
# nightly dump, compressed
mysqldump --single-transaction --routines app | gzip > app-$(date +%F).sql.gz
# pipe straight into encrypted, versioned storage
mysqldump --single-transaction app | restic backup --stdin --stdin-filename app.sql
--single-transactiongives a consistent snapshot without locking the DB. Automate with a nightly timer and test restores — an untested backup is a guess. See Encrypted Backups with restic.
Replication — live copies
A primary streams its changes to one or more replicas:
| Use | How |
|---|---|
| Read scaling | Send reads to replicas |
| Failover / HA | Promote a replica if the primary dies |
| Off-box safety | Replica on another host |
Replication is not a backup. It faithfully copies your mistakes too —
DROP TABLEreplicates instantly. Keep real backups alongside it.
The rule
3-2-1: three copies, two media, one off-site. Encrypt at rest, and rehearse the restore before you need it.
Related: Encrypted Backups with restic · MariaDB Socket Auth vs TCP Users · Docker Compose for Self-Hosting