Bitte von dem langen Text nicht abschrecken lassen. Leider kann ich es nicht kürzer beschreiben, ohne dass Verständnisschwierigkeiten auftreten. Vielen Dank für das Verständnis!
Hallo zusammen …
ich stehe vor einem großen Problem beim Einrichten des täglichen Backups von meiner Postgres-9 Datenbank. Bevor ich meine Frage vorstelle, möchte zuvor kurz den aktuellen Stand beschreiben:
Wir bauen gerade eine große Archivdatenbank auf. In dieser Datenbank sollen die Daten 10 Jahre lang vorgehalten werden. Da nur auf die letzten 12 Monate performant zugegriffen werden können soll, habe ich mich dazu entschieden, die entsprechenden Archivtabellen zu partitionieren und nur bei den entsprechenden Teiltabellen einen Index vorzusehen, die innerhalb dieser 12 Monate liegen. Mir ist bekannt, dass man auch einen partiellen Index hätte nutzen können - später dazu mehr.
Nun zum Backup: Da es sich um eine relativ große Datenbank handelt und ein Full-Backup momentan 8h dauert und in naher Zukunft voraussichtlich länger als 48h dauern wird, kommt m.E. nur ein differentielles Backup in Frage. Ein Full-Backup soll nur in Ausnahmefällen geschehen. Entsprechend pessimistisch ist meine Prognose zum Recovery, d.h. bei einem Recovery eines differentiellen Backups, muss mindestens 48h angesetzt werden + x Stunden, um das WAL nachzuspielen. Somit könnte m.E. schnell mehrere Tage zusammenkommen, um ein Recovery abzuschließen. Dieses ist nicht akzeptabel. Daher habe ich mir folgende Lösung einfallen lassen:
Ich baue eine WAL-Replikation der Datenbank auf. Mit Posgres-9 ist dieses möglich und hat m.E. den Vorteil, dass neue Tabellen und Tabellenänderungen nicht vorher aufwändig konfiguriert werden müssen. Vom Slave wird die Datensicherung gemacht. Dieses geschieht mit pg_dump. Dieser Ansatz muss allerdings noch verfeinert werden. Daher arbeite ich mit Triggern, d.h. zunächst hefte ich auf dem Slave an allen Tabellen (auch den partitionierten Tabellen) einen Trigger. Der Trigger reagiert auf create, update und delete. Wird der Trigger ausgelöst, löscht sich der Trigger von der entsprechenden Tabelle. Zum Zeitpunkt des Backups, stoppe ich die Replikation und schaue, welche Tabellen keinen Trigger besitzen und sichere diese. Danach installiere ich wieder an allen Tabellen den Trigger und starte die Replikation. Wo liegen die Vorteile dieses Verfahrens:
Wird eine neue Tabelle auf dem Master angelegt, wird diese ohne weiteres Zutun auf dem Slave automatisch gesichert, weil diese ja keinen Trigger besitzt. Desweiteren ist dieser Ansatz mit dem Trigger recht effizient, da dieser (idealerweise) nur einmal zwischen zwei Backups ausgelöst wird. Durch pg_dump werden die Tabellen voll gesichert. Die Partionierung reduziert das Datenvolumen aber erheblich. Spannend ist auch das Recovery, d.h. es können die aktuellen Teiltabellen der Partitionierung zuerst und diese innerhalb weniger Stunden wiederhergestellt werden, sodass die Benutzer mit dem wichtigsten Teil der Daten schon wieder arbeiten können. Die älteren Daten können im laufenden Betrieb “reingeschoben” werden.
Den Mechanismus mit den Trigger habe ich schon realisiert und erfolgreich getestet. Ich scheitere momentan daran, die WAL-Replikation einzurichten. Dieses liegt aber sicherlich daran, dass ich an irgendeiner Stelle die Anleitung nicht richtig befolge. Dieses soll auch hier nicht weiter relevant sein. Nach dem ersten Fehlversuch bin ich allerdings auch schon beim Lesen auf den Abschnitt mit den Einschränkungen der WAL-Replikation gestoßen. Da heißt es, dass nur lesender Zugriff auf dem Slave möglich ist.
Daher folgende Fragen:
- Ist die Annahme richtig, dass ich auf dem Slave keinen Trigger installieren kann aufgrund der Lesezugriffbeschränkung?
- Könnte ich diese Beschränkung umgehen, indem ich die DB herunterfahre, die Replikation deaktiviere z.B. durch umbenennen von “recovery.conf”, die DB starte, das Backup mache, die DB stoppe, die Replikation wieder reaktiviere und dann die DB starte?
- Wenn 1. oder 2. nicht funktionieren, was kann ich alternativ machen?
Vielen Dank für eure Ausdauer und Beteiligung zur Klärung meiner Fragen im Voraus!
- Dieter.