Kluges Backup Management

Hallo,
schön, dass man zwischendurch auch mal was in eigener Sprache zum Thema lesen kann. Ich hatte schon befürchtet, meine Frage in Lothar-Matthäus Stil formulieren zu müssen. Vorweg: ich würde eher von mir behaupten, dass mein Wissen über PostgreSQL und DBen… naja… sagen wir bestenfalls unvollständig ist.

Ich hoffe, dass ich hier mit meiner Frage richtig bin:
wie muss ich die Backups “meiner” DB konfigurieren, damit ich so aktuell und effizient wie möglich eine Sicherung der kompletten DB habe?

Installiert ist postgreSQL 9.1.9. Die DB umfasst 40 Tabellen mit mehreren Millionen Einträgen, täglich um mehrere tausend (evtl. auch zehtausend, kommt drauf an…) Einträge wachsend. Ich bin nicht sicher, ob das besonders relevant ist, aber es werden oids eingesetzt. Ferner gibt es zehntausende bytea-Objekte, die für das Ganze Prozedere zeitlich gesehen ein große Rolle zu spielen scheinen. Jedenfalls wurde mir zum Anlegen eines Backups der Befehl
pg_dumpall --clean --oids --username=postgres > /…/dump.sql
ans Herz gelegt. Im Ergebnis entspricht der Dump auch dem, was ich brauche, nur ergeben sich aus der Größe der DB damit mehrere Unannehmlichkeiten:

das Anlegen des Dumps dauert auf eine interne Platte ca. 1 Stunde, auf eine USB-Platte entsprechend länger. Das Backup soll nach Möglichkeit in einem anderen Raum (physisch) liegen, weshalb der Dump auf die interne Platte nur als Zwischenspeicherung in Frage kommt. Diese Zeit (1 Stunde) ist erträglich, obwohl die DB unter der Woche rund um die Uhr gebraucht wird.
Viel ärgerlicher ist aber die Zeit, die dann im Falle eines Sterbens der Festplatte gebraucht wird, um das Backup auf einem Server wieder einzuspielen. Ich habe die Zeit zwar nicht gestoppt, aber das schien zumindest mal > 6 Stunden zu brauchen, evtl. auch deutlich länger.

Nun also: gibt es eine Möglichkeit, die DB zumindest täglich wie beschrieben zu sichern? Ich stelle mir das idealer Weise so vor: ich erstelle einmalig einen kompletten Dump und spiele diesen auf einem Backup-Server ein. Jeden Tag wird dann ein Zwischenbackup von den Veränderungen seit dem letzten Zwischenbackup (spannende Frage: gibt’s sowas?) erstellt. Falls es so eine Funktion gibt, müsste das Ergebnis ja klein und schnell einzuspielen sein. Nach 7 Tagen könnte man dann die 7 Zwischenbackups auf dem Backup-Server einspielen, sodass dieser im Zweifelsfall schnell einsatzfähig ist (ohne die stundenlange Warterei auf das Einspielen des gesamten Dumps).

Geht das?

Dankbar für’s Durchlesen der Frage und jeden Hinweis, auch wo ich mal nachlesen sollte,
Jens

Relevant ist das nicht, nur dumm :wink:

Ferner gibt es zehntausende bytea-Objekte, die für das Ganze Prozedere zeitlich gesehen ein große Rolle zu spielen scheinen. Jedenfalls wurde mir zum Anlegen eines Backups der Befehl
pg_dumpall --clean --oids --username=postgres > /…/dump.sql

Viel ärgerlicher ist aber die Zeit, die dann im Falle eines Sterbens der Festplatte gebraucht wird, um das Backup auf einem Server wieder einzuspielen. Ich habe die Zeit zwar nicht gestoppt, aber das schien zumindest mal > 6 Stunden zu brauchen, evtl. auch deutlich länger.

Du hast nur eine DB zu sichern? Dann pg_dump mit -Fc gewürzt. Dann kannst Du bei Restore in mehreren Jobs arbeiten.

Nun also: gibt es eine Möglichkeit, die DB zumindest täglich wie beschrieben zu sichern? Ich stelle mir das idealer Weise so vor: ich erstelle einmalig einen kompletten Dump und spiele diesen auf einem Backup-Server ein. Jeden Tag wird dann ein > Zwischenbackup von den Veränderungen seit dem letzten Zwischenbackup > (spannende Frage: gibt’s sowas?) erstellt. Falls es so eine Funktion gibt, müsste das Ergebnis ja klein und schnell einzuspielen sein. Nach 7 Tagen könnte man dann die 7 Zwischenbackups auf dem Backup-Server einspielen, sodass dieser im Zweifelsfall schnell einsatzfähig ist (ohne die stundenlange Warterei auf das Einspielen des gesamten Dumps).

Geht das?

Wenn Du eh einen Backup-System hast, wo die Daten eingespielt werden, was spricht gegen Streaming Replication?

Danke für die Hinweise!

Die DB ist nach heutigem Maßstab uralt. Ich glaube, in der Zeit, aus der sie ursprünglich stammt, waren OIDs Standard.

Zu den beiden Möglichkeiten:
Custom-Format: Lässt sich etwas über die relative Zeitersparnis gegenüber dem plain-Format sagen? Wichtig ist im Prinzip nur die Zeitersparnis beim restore. Wenn’s nachts durch den dump mal ne Stunde langsamer ist, kann man das eher verkraften als im Falle eines Crashs die zig Stunden restore-Zeit.

Streaming Replication
Klingt vielversprechend. Verstehe ich das richtig, dass dabei alles, was auf der Master-DB passiert, in eine lokale Datei geschrieben wird und der Slave seine DB entsprechend aktualisiert? Damit würde die restore-Wartezeit ja komplett wegfallen und der Verlust wäre im Falle des Crashs quasi null? Klingt gut! Eigentlich war es erklärtes Ziel, den Backup-Server nach Möglichkeit so wenig wie möglich einzuschalten, in der Hoffnung, dass er so etwas von seiner Jungfräulichkeit behält. Aber dass beide gleichzeitig abrauchen ist wohl reichlich unwahrscheinlich.

Verstehe ich es ferner richtig: ich muss, um diese Funktion aufschalten zu können, erstmal Master und Slave auf exakt den gleichen Stand bringen? Oder geht das jetzt im Nachhinein sogar gar nicht mehr so ohne weiteres?
Gibt es dadurch Nachteile wie Performance-Verlust?
Es ist außerdem so, dass zu bestimmten Uhrzeiten “massenhaft” Daten in die DB geschrieben werden mitsamt größen bytea-Einträgen, sodass mal in wenigen Sekunden einige MB zusammenkommen. Tut das irgendwas zur Sache (Stichwort buffer…)?

Danke für die Hilfe!

Deine 9.1 ist noch nicht so alt. OID’s waren mal zu Zeiten 7.x oder so Mode.

Zu den beiden Möglichkeiten:
Custom-Format: Lässt sich etwas über die relative Zeitersparnis gegenüber dem plain-Format sagen? Wichtig ist im Prinzip nur die Zeitersparnis beim restore.

Kommt drauf an. Wenn Du viele kerne hast und ein schnelles IO-System und viele etwa gleich große Tabellen lohnt sich das. Hast Du nur 1 Big-Table, um die es geht, dann ist der Gewinn eher gleich NULL.

Streaming Replication
Klingt vielversprechend. Verstehe ich das richtig, dass dabei alles, was auf der Master-DB passiert, in eine lokale Datei geschrieben wird und der Slave seine DB entsprechend aktualisiert?

Nein. Ein Slave, der SR macht, meldet sich beim Master an. Dieser schickt ab dann alles, was da ein COMMIT bekommt, an den Slave. Ab 9.2 geht das auch synchron, dann ist Master und Slave immer auf dem selben Stand. Hat nur den Nachteil, daß Master und Slave stehen, wenn jemand das Kabel dazwischen durchschneidet.

Damit würde die restore-Wartezeit ja komplett wegfallen und der Verlust wäre im Falle des Crashs quasi null? Klingt gut!

Jupp. Du brauchst nur eine Instanz, der dem Slave sagt, daß er nun Master ist. Bis dahin kannst den Slave sogar für lesende Abfragen nutzen. Es gibt eine Reihe von Lösungen wie pgpool etc.

Eigentlich war es erklärtes Ziel, den Backup-Server nach Möglichkeit so wenig wie möglich einzuschalten, in der Hoffnung, dass er so etwas von seiner Jungfräulichkeit behält.

Ach gottchen, …

Aber dass beide gleichzeitig abrauchen ist wohl reichlich unwahrscheinlich.

Bei einem Hardware-Ausfall sind die Kosten der Hardware fast immer zu vernachlässigen im Vergleich zu den Kosten verlorener Daten, falls diese mit sterben. Das muß man halt abwägen.

Verstehe ich es ferner richtig: ich muss, um diese Funktion aufschalten zu können, erstmal Master und Slave auf exakt den gleichen Stand bringen?

Ja.

Oder geht das jetzt im Nachhinein sogar gar nicht mehr so ohne weiteres?

Nein. Also, das geht auch bequem im Nachinein einzurichten. Ohne große Downtime des Masters (nur das WAL muß passend gesetzt sein und es müssen WAL-Sender laufen). Ist der Maste rerst einmal für SR eingerichtet kannst im laufenden Betrieb neue Slaves drankleben ohne Downtime.

Gibt es dadurch Nachteile wie Performance-Verlust?

Faktisch nicht messbar.

Es ist außerdem so, dass zu bestimmten Uhrzeiten “massenhaft” Daten in die DB geschrieben werden mitsamt größen bytea-Einträgen, sodass mal in wenigen Sekunden einige MB zusammenkommen. Tut das irgendwas zur Sache (Stichwort buffer…)?

Danke für die Hilfe!

Das ist 'ne andere Sache, unabhängig von SR oder nicht sollte man das passend konfigurieren.

Passende Hardware und Setup vertragen schon einige hundert Inserts/Sekunde und das auch mit SR.

He man, danke für die ausführliche Antwort!

Dann wird’s die streaming replication. Wegen Synchronität würde ich behaupten, dass in meinem Fall auf die eine Sekunde (selbst eine Minute wäre auch nicht tödlich…) verzichtet werden kann.

Abschließend dann zum Verständnis eine letzte Frage zur Vorgehensweise: ich nehme die DB vom Netz, mache einen pg_dumpall (für das eine geplante Mal ist der Zeitfaktor irrlevant…) und spiele den Dump anschließend auf dem Backup-Server ein. Das Setup würde ich dann nach dieser Beschreibung hier vornehmen: http://blog.thecodepath.com/2012/02/13/adventures-in-scaling-part-3-postgresql-streaming-replication/
Gibt es gegen diese aus dem Stand Einwände? Sieht recht detailliert aus, sodass es hoffentlich keine Überraschungen gibt…


Übrigens: die DB ist wahrlich ein paar Jahre alt, allerdings hat sie aufgrund eines Serverumzugs vor knapp einem Jahr ein Upgrade verpasst bekommen, daher die 9.1 :wink:

das sind eher so Millisekunden …

Abschließend dann zum Verständnis eine letzte Frage zur Vorgehensweise: ich nehme die DB vom Netz,

Nein. pg_basebackup oder händisch via pg_start_backup() un drsync oder so, lies endlich die Doku…

mache einen pg_dumpall

Nein, Das ist ein logischen Backup, Du brauchst ein physisches. Um es mal so zu vergleichen.

http://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CDAQFjAA&url=http%3A%2F%2Fandreas.scherbaum.la%2Fwritings%2Fclt-2013-pg-replication-92-print.pdf&ei=_fRzUu6FDIjNswan8YCADQ&usg=AFQjCNGMO98l5bflJ9gPIsaWJwClRHQcDA&sig2=T5MZ9MEJCoB7Qt4SEElLMA&bvm=bv.55819444,d.Yms&cad=rja

(ich hoffe, der Link funktioniert …)

Andreas

Nein. pg_basebackup oder händisch via pg_start_backup() un drsync oder so, lies endlich die Doku…

Nagut, das habe ich befürchtet. Grundsätzlich bin ich schon bereit dazu und habe auch in der Dokumentation gelesen. In diesem Fall habe ich aber eine bestehende DB und ein konkretes, einmaliges Vorhaben. Dazu nun die Dokumentation ganz durchzuarbeiten empfinde ich irgendwie als overkill.

Mein Verständnisproblem, auch mit der Dokumentation, ist eben, dass “überall” (auch auf dem von dir verfassten Papier) von neu aufgesetzten Datenbanken ausgegangen wird. Meine letzte Frage also: wie bringe ich beide auf den gleichen Stand. In diesem Sinne, da es eine einmalige Nummer wird, machen vereinfachende Umstände wie “erstmal DB vom Netz nehmen” intuitiv Sinn für mich → dann dumpen und los gehts… Oke, ist Quatsch - hab ich verstanden.

Aber: wenn pg_basebackup durch ist und ich die Datenbanken danach stoppe, es also zu keinen Transaktionen danach mehr kommt, kann ich doch in aller Seelenruhe das Setup für das SR durchführen!? Oder muss ich das in einem Rutsch mit dem basebackup in die Wege leiten?

All Deine Fragen sind in den von mir genannten Links mehr als hinreichend beantwortet.

Andreas

Links? Plural? Deinem Link folgend komme ich hierhin: http://andreas.scherbaum.la/writings/clt-2013-pg-replication-92-print.pdf
Inwiefern wird dort meine Frage beantwortet?

Ich nannte mehr als genug Stichworte. Das Thema erfordert, daß man sich intensiv damit beschäftigt.

Alternativ: Du kannst das bei uns hosten lassen. Dann kümmern wir uns drum. Aber Doku-Vorlese-Service bekommst hier von mir nicht.

In Ordnung, dann danke ich für die helfenden Stichworte

Ich vertraue darauf, dass sich die Macher des ganzen mit dem Thema intensiv beschäftigt haben und werde einfach nach dieser Anleitung vorgehen: http://www.rassoc.com/gregr/weblog/2013/02/16/zero-to-postgresql-streaming-replication-in-10-mins/

Dort ist das Prozedere in Reihenfolge mit Script beschrieben.