Dein Uberspace wird automatisch jede Nacht vollständig auf einem externen Backupserver von uns gesichert. Wir haben uns, nachdem wir im Lauf der Jahre mit verschiedensten Backup-Techniken und -Tools experimentiert haben, für eine Variante entschieden, die mit Abstand am einfachsten zu administrieren ist und keiner speziellen Tools bedarf, um auf die Backups zugreifen zu können. Sie ist zwar nicht die performanteste oder effektivste Möglichkeit, aber nach unseren Erfahrungen absolut „rock-solid“, und darauf kommt es bei einer Datensicherung schließlich an.
Die Backups werden initiativ von unseren Backupservern aus durchgeführt (d.h. nicht der Hosting-Server schiebt sein Backup dorthin, sondern der Backupserver zieht sich das Backup vom Hostingserver) und werden von unserem Backupserver aus via NFS read-only auf dem betreffenden Uberspace-Server gemountet. Wir haben das aus drei Gründen so realisiert:
Auf diese Weise gibt es vom Hosting-Server aus gar keinen direkten Zugriff auf den Backup-Server. Das ist wichtig für den Fall, dass ein Hacker den kompletten Hosting-Server kompromittieren würde: Normalerweise könnte er das Backup dann gleich mit kompromittieren; hier ist das nicht möglich. Er müsste dann schon separat auch noch den Backup-Server hacken.
Durch die Read-Only-Einbindung via NFS ist sichergestellt, dass du zwar jederzeit lesend Zugriff auf das Backup hast, aber eben nicht schreibend. Fälle wie „Sch…, jetzt habe ich mein eigenes Backup gelöscht“ kann es von daher also auch nicht geben.
Da das Backup auf einem externen Server liegt, zählt es nicht zu deiner Quota, obwohl via NFS alle Berechtigungen der Dateien im Backup und damit auch die Eigentümerschaft bei dir liegt.
Der Vollständigkeit halber sei erwähnt, dass wir das Backup auch auf korrekte Funktion überwachen. Fälle wie „Oh, jetzt wo du ein Backup brauchst, merken wir gerade … der Backup-Job läuft aufgrund eines Bugs ja schon seit einem halben Jahr nicht mehr!“ (ja, alles schon bei anderen Providern erlebt) werden damit bei uns effektiv vermieden.
Bitte nicht wundern: Beim Zugriff auf die Backupdateien wirst du bei weitem nicht die gleiche Performance haben können wie beim Zugriff auf deinen produktiven Datenbestand - das ist schlicht der langsameren Übertragung via NFS geschuldet, und ein wenig auch der langsameren Performance der Backupserver (insbesondere während gerade aktiv Backups durchgeführt werden).
Die Sache ist relativ simpel: Wir führen nächtlich via rsync über eine verschlüsselte SSH-Verbindung eine vollständige Synchronisation des Servers mit allen Uberspaces auf ein separates System durch (mit Ausnahme der Datenbanken, die wir separat behandeln). Dabei verwenden wir pro Tag ein separates Verzeichnis: daily.0 ist sozusagen das „Arbeitsverzeichnis“; das aktuelle Backup letzter Nacht findest du in daily.1, in daily.2 das für den Tag davor, etc. - dabei legen wir Hardlinks an, damit eine Datei, die tagelang unverändert vorlag, auch nur einmal auf dem Backupserver liegt und nicht unnötig Platz verschwendet. Sobald sich eine Datei geändert hat, wird der Hardlink aufgelöst und zwei verschiedene Stände der Datei gesichert.
„Dateien“ umfasst hier also wirklich alles, sowohl die Inhalte deines DocumentRoots als auch deine Mails, deine Konfiguration etc.; wie gesagt, lediglich die Datenbanken behandeln wir separat.
Auf dem Hosting-Server, auf dem dein Uberspace liegt, hast du direkten Zugriff auf das Backup, das du in /backup findest. So sieht das aus:
[elena@neon ~]$ ls -ltr /backup/
total 72
drwxr-xr-x 25 root root 4096 Dec 15 08:08 daily.14
drwxr-xr-x 25 root root 4096 Dec 16 07:58 daily.13
drwxr-xr-x 25 root root 4096 Dec 17 03:30 daily.12
drwxr-xr-x 25 root root 4096 Dec 18 03:05 daily.11
drwxr-xr-x 25 root root 4096 Dec 19 03:24 daily.10
drwxr-xr-x 25 root root 4096 Dec 21 04:30 daily.9
drwxr-xr-x 25 root root 4096 Dec 22 03:51 daily.8
drwxr-xr-x 25 root root 4096 Dec 23 05:16 daily.7
drwxr-xr-x 25 root root 4096 Dec 24 03:27 daily.6
drwxr-xr-x 25 root root 4096 Dec 25 03:38 daily.5
drwxr-xr-x 25 root root 4096 Dec 26 02:56 daily.4
drwxr-xr-x 25 root root 4096 Dec 28 04:11 daily.3
drwxr-xr-x 25 root root 4096 Dec 29 03:50 daily.2
drwxr-xr-x 25 root root 4096 Dec 30 03:53 daily.1
drwxr-xr-x 25 root root 4096 Dec 30 03:53 daily.0
drwxr-xr-x 472 root root 12288 Dec 30 06:35 mysqldumps
Du hast versehentlich dein Verzeichnis /var/www/virtual/elena/html/blog gelöscht, und zwar schon vor, sagen wir mal, drei Tagen (und dir ist es erst heute aufgefallen)? Das ist kein Problem, denn es gibt ja eine vollständige Kopie:
[elena@neon ~]$ ls -ld /backup/daily.3/var/www/virtual/elena/html/blog
drwxr-xr-x 12 elena elena 4096 Dec 12 23:31 /backup/daily.3/var/www/virtual/elena/html/blog
Du kannst also mit den ganz normalen Linux-Bordmitteln wie ls, cp, rsync etc. mit dem Backup hantieren, zum Beispiel einen Restore durchführen:
[elena@neon ~]$ rsync -av /backup/daily.3/var/www/virtual/elena/html/blog/ /var/www/virtual/elena/html/blog/
Wenn du Hilfe brauchst und dich auf der Shell (noch) nicht sicher genug fühlst, um dir ein Backup selbst wiederherstellen zu können, melde dich einfach bei uns und wir unterstützen dich gerne dabei.
Wir haben lange gerätselt, wie sich MySQL-Datenbanken am vernünftigsten sichern lassen. Ein dateibasiertes Backup fällt hier nämlich aus: Finden während des Backups schreibende Zugriffe auf eine Tabelle statt, so ist diese im schlimmsten Fall im Backup korrupt und damit völlig unbrauchbar. Die sauberste Möglichkeit ist, einen Dump einer Tabelle anzufertigen, also eine Textdatei mit genau den SQL-Statements, die eine Tabelle anlegen und mit dem derzeitigen Datenbestand füllen. Das funktioniert auch prima, hat aber den „kleinen“ Nachteil, das während dieses Dumps die Tabelle gesperrt („gelockt“) ist und keine Schreibzugriffe darauf stattfinden können - sicherlich kein Problem bei kleineren Tabellen; für Tabellen, deren Backup minutenlang dauert, aber sehr wohl. Wir haben unsere MySQL-Server auf den Hosting-Servern daher jeweils in einer Master-Slave-Replikation aufgebaut: Der Slave enthält stets eine komplette Kopie aller Daten und wird live synchronisiert. Geht es nun des Nachts an die Backups, stoppen wir den Slave - der Master arbeitet dabei weiter! - ziehen uns Dumps von ihm und starten ihn anschließend wieder, woraufhin er sich automatisch wieder mit dem Master synchronisiert. Das liest sich alles simpler, als es faktisch umzusetzen ist - wenn du dich für die Details interessierst, kannst du dir unsere Postings auf blog.jonaspasche.com dazu anschauen.
Alle MySQL-Dumps findest du unter /backup/mysqldumps/DeinUberspace. So sieht das dann aus:
[elena@neon ~]$ ls -l /backup/mysqldumps/elena/
total 20
drwxr-sr-x 2 root elena 4096 Dec 25 06:19 2010-12-25_06-19-09
drwxr-sr-x 2 root elena 4096 Dec 26 05:10 2010-12-26_05-10-42
drwxr-sr-x 2 root elena 4096 Dec 28 06:49 2010-12-28_06-48-55
drwxr-sr-x 2 root elena 4096 Dec 29 06:31 2010-12-29_06-29-59
drwxr-sr-x 2 root elena 4096 Dec 30 06:34 2010-12-30_06-34-25
MySQL-Dumps können im Gegensatz zu den dateibasierten Backups nicht inkrementell angelegt werden; ein solches Feature gibt es in Dumps aus strukturellen Gründen schlicht nicht. Wir können hier von daher nicht die vollen 14 Tage rückwirkend an Daten anbieten wie beim dateibasierten Backup (schlicht deshalb, weil die Datenmenge dann zu groß wird), aber zumindest einige Tage halten wir immer vor.
Damit du nicht nur „alles oder nichts“ wiederherstellen kannst, sichern wir jede Tabelle in einer separaten Datei und komprimieren diese mit gzip. So sieht das dann aus:
[elena@neon ~]$ ls -l /backup/mysqldumps/elena/2010-12-25_06-19-09/
total 220
-rw-r--r-- 1 root elena 1868 Dec 25 06:19 elena_account.sql.gz
-rw-r--r-- 1 root elena 838 Dec 25 06:19 elena_openid.sql.gz
-rw-r--r-- 1 root elena 1101 Dec 25 06:19 elena_session.sql.gz
-rw-r--r-- 1 root elena 848 Dec 25 06:19 elena_transaction.sql.gz
Du kannst insofern problemlos einzelne Tabellen einspielen, und zwar beispielsweise so:
[elena@neon ~]$ zcat /backup/mysqldumps/elena/2010-12-25_06-19-09/elena_account.sql.gz | mysql elena
Da deine MySQL-Zugangsdaten in deiner .my.cnf hinterlegt sind, bedarf es hier keiner Eingabe von MySQL-Zugangsdaten. Hast du dir versehentlich eine komplette Datenbank weggehauen? Auch kein Problem; du musst natürlich nicht jede Tabelle einzeln wieder einspielen:
[elena@neon ~]$ zcat /backup/mysqldumps/elena/2010-12-25_06-19-09/elena_*.sql.gz | mysql elena
Auch hier gilt natürlich: Wenn du Hilfe brauchst und dich auf der Shell (noch) nicht sicher genug fühlst, um dir ein Backup selbst wiederherstellen zu können, melde dich einfach bei uns und wir unterstützen dich gerne dabei.