Wie kann man warten, bis PostgreSQL startbar / wiederherstellbar ist?

8

Ich teste ein Upgrade von PostgreSQL 8.2.1 auf 9.2 auf einer virtuellen Maschine, auf der eine benutzerdefinierte Linux-Distribution ausgeführt wird. Das Upgrade-Verfahren ist wie folgt:

  1. Starten Sie den pgDienst
  2. Saugen Sie alle DBs ab (nicht sicher, ob dies erforderlich ist)
  3. Backup mit pg_dumpall
  4. Beenden Sie den pgDienst
  5. Verschieben Sie das Verzeichnis, in dem die Daten gespeichert sind ( /var/pges handelt sich um eine einfache Einrichtung mit nur einem Server).
  6. Installieren Sie PostgreSQL 9.2
  7. initdb
  8. Starten Sie den Server
  9. Stellen Sie die gespeicherten Daten wieder her
  10. reindexdb alle DBs
  11. Erstellen Sie die referential_constraintsAnsicht neu
  12. Staubsaugen Sie alle DBs (AFAIK nach diesem Upgrade erforderlich)

Dieses Verfahren funktioniert problemlos auf einem Host und kann problemlos gesichert und wiederhergestellt werden. Auf einem anderen Computer mit einer anderen Datenbank funktionieren die Punkte 1 bis 7 einwandfrei, aber der Server wird erst gestartet, wenn ich ein sleep 1After hinzufüge initdb, und selbst dann können die ausgegebenen Daten nicht wiederhergestellt werden, da "das Datenbanksystem gestartet wird". Was sind die Standardmethoden, um damit umzugehen, abgesehen von diesen schrecklichen Hacks:

  1. sleepfür eine großzügige Zeitspanne vor jeder Operation,
  2. Schleifen, bis es funktioniert oder bis eine großzügige Zeitüberschreitung erreicht ist, oder
  3. Schleife, bis eine triviale Abfrage akzeptiert wird oder eine Zeitüberschreitung erreicht ist.

Edit: Die " Lösung " hat doch nicht funktioniert. Was ist erforderlich, um sicherzustellen, dass die Datenbank bereit ist, eine Wiederherstellung auszuführen?

l0b0
quelle
Nur eine Idee: Können Sie den initdbExit-Status testen ? Ich nehme an, wenn die Arbeit erledigt ist.
Dekso
@dezso Nein, initdbwird synchron ausgeführt, sodass der Start des Servers initdbbereits erfolgreich abgeschlossen wurde.
10b0
Dann habe ich keine bessere Idee, als einen einfachen Test zu wiederholen, der überprüft, ob die Dinge fertig sind.
Dekso
2) wird nicht benötigt. 10) wird ebenfalls nicht benötigt, da durch das Wiederherstellen des Speicherauszugs alle Indizes neu erstellt werden.
a_horse_with_no_name

Antworten:

5

initdb kehrt erst zurück, wenn es fertig ist. Daher sollte zwischen dem Start und dem Serverstart keine Pause erforderlich sein. Es gab Fehler in PostgreSQL, bei denen es abgeschlossen wurde, ohne dass zuerst alles auf die Festplatte geschrieben wurde. Ich kenne momentan keine Links, aber die Natur der Fehler ist, dass Sie nicht immer über sie Bescheid wissen.

Wenn Sie den Befehl pg_ctl zum Starten der Datenbank verwenden, warten Sie mit den Parametern "-w", bis der Start abgeschlossen ist, bevor Sie zurückkehren. Es macht nichts Besonderes - es macht nur das "Ist es schon fertig?" Schleife für Sie.

Beachten Sie, dass bei einem Serverabsturz mit vielen Daten, die erneut abgespielt werden müssen, bevor der Server gestartet werden kann, das durch "-t" beim Warten auf pg_ctl festgelegte Zeitlimit möglicherweise zu niedrig ist.

Es gibt keinen Grund, die Quelldatenbanken VACUUM zu machen, bevor Sie einen pg_dump von ihnen ausführen. Während es den Dump etwas beschleunigen könnte, wird das Vakuum selbst länger dauern als diese Verbesserung.

Greg Smith
quelle
Ist der 12. Schritt erforderlich? Ich würde erwarten, dass die Tabellen zusammenhängend sind (oder nach einem pg_restore -j{morethan1} fast zusammenhängend ).
Dekso
Wir laufen postmaster, um den Daemon zu starten, und es scheint keine solche Option zu geben.
10b0
2

Das ArbeitenEine fehlerhafte Lösung bestand darin, das Init-Skript so zu ändern, dass wiederholt überprüft wird, ob der entsprechende Port verwendet wird. Wenn es nach einer Minute nicht angezeigt wird, gilt der Start als fehlgeschlagen. Pseudocode:

start() {
    pg start
    checks=0
    while checks < 30:
        return true if the port is in use
        sleep 2
        checks++
    return false
}

Bearbeiten: Es stellt sich heraus, dass dies nicht ausreicht. Der Wiederherstellungsschritt:

PGOPTIONS='--client-min-messages=warning' psql \
    --no-psqlrc \
    --variable=ON_ERROR_STOP=1 \
    --quiet \
    --log-file="$restore_log" \
    --single-transaction \
    --username postgres \
    --file="$sql_backup"

Fehlermeldung:

psql: FATAL:  the database system is starting up
l0b0
quelle