Reinstall nötig nach rsync Backup/Restore

Raspberry Pi 4B, Bullseye 64, Postgresql 14

Ich verwende das Script “raspiBackup” um die Partitionen “/” und “/boot” per rsync auf mein QNAP per NFS zu sichern. Unter Buster hat das einwandfrei funktioniert. Seit dem Upgrade auf Bullseye startet postgresql nach einem restore nicht mehr. Im Log findet man:

2021-11-21 11:15:11.838 CET [842] LOG:  received fast shutdown request
2021-11-21 11:15:11.842 CET [842] LOG:  aborting any active transactions
2021-11-21 11:15:11.843 CET [2735] <user>@<server> FATAL:  terminating connection due to administrator command
2021-11-21 11:15:11.849 CET [842] LOG:  background worker "logical replication launcher" (PID 884) exited with exit code 1
2021-11-21 11:15:11.866 CET [879] LOG:  shutting down
2021-11-21 11:15:11.970 CET [842] LOG:  database system is shut down
/usr/lib/postgresql/14/bin/postgres: error while loading shared libraries: libicui18n.so.63: cannot open shared object file: No such file or directory
no data was returned by command ""/usr/lib/postgresql/14/bin/postgres" -V"
The program "postgres" is needed by pg_ctl but was not found in the
same directory as "/usr/lib/postgresql/14/bin/pg_ctl".
Check your installation.
/usr/lib/postgresql/14/bin/postgres: error while loading shared libraries: libicui18n.so.63: cannot open shared object file: No such file or directory
no data was returned by command ""/usr/lib/postgresql/14/bin/postgres" -V"
The program "postgres" is needed by pg_ctl but was not found in the
same directory as "/usr/lib/postgresql/14/bin/pg_ctl".
Check your installation.

Unter Buster hatte ich die DB vor dem Backup jeweils stillgelegt mit “systemctl stop postgresql” und nach dem Restore wieder in Betrieb genommem mit “systemctl start postgresql”. Aufgrund der PG Dokumentation habe ich das Verfahren zur Stilllegung der DB geändert in “pg_ctlcluster 14 main stop” und nach dem Restore “pg_ctlcluster 14 main start”. Der Fehler der dabei erzeugt wurde war nicht derselbe wie oben, aber mit “systemctl start postgresql” wird er wieder erzeugt.

Ein “apt --reinstall install postgresql-14” behebt das Problem. Wäre aber schön, wenn ich das nicht jedes mal tun müsste.

Wenn jemand das Problem kennt und weiss, wie man es behebt, würde mich ein Hinweis freuen.

Zum Backup von Datenbanken solltest Du grundsätzlich NICHT auf Filesystem-Tools zurückgreifen, sondern Tools auf Datenbankebene wie pg_dump oder pg_dumpall benutzen.

Prüf mal ob die Rechte nach dem Restore noch passen und ob alle Gruppen und Benutzer sauber angelegt sind, das könnte solche Fehler auch verursachen.

Natürlich kannst Du mit Filesystem Tools ein Backup/Restore machen. Da Du die Datenbank vorher stoppst ist das gar kein Problem.

Es sieht so aus, als würde die Postgres Installation nicht vollständig gesichert. Ist /var unter Buster eine eigene Partition? Wo liegt die Library, deren Fehler beim Start angemeckert wird?

Danke Beide für die Unterstützung.

@eschwenk

Ich habe mal versucht die Zustände der funktionstüchtigen Instanz (vor dem Backup) mit jenen der fehlerhaften Instanz (nach dem Restore) bezüglich Rechten, Gruppen und Benutzern zu vergleichen:

<user>@<host>:/usr/lib/postgresql/14/bin $ ls -l keine Unterschiede in der Ausgabe, “/usr/lib/postgresql/14/bin” ist das Verzeichnis, das im Log erwähnt wird.

<user>@<host>:~ $ nano /etc/group keine Unterschiede in der Ausgabe

<user>@<host>:/usr/lib/postgresql/14/bin $ getent passwd keine Unterschiede in der Ausgabe.

Ich weiss nicht, ob das genügt um sagen zu können, dass es keine Unterschiede gibt zwischen den Instanzen.

Das Verfahren auf Dateisystemebene habe ich unter Buster mehrfach erfolgreich eingesetzt um eine fehlerhafte Instanz auf einen früheren, funktionierenden Zustand zurückzusetzen. Wenn ich es richtig beurteile, müsste ich mit “pg_dump” jedesmal das System platt machen, neu aufsetzen und am Schluss mit “pg_restore” die Daten wieder in die DB einfügen.

@robopgmobil

“/var” ist sowohl unter Buster wie unter Bullseye keine eigene Partition. Es gibt nur die Partitionen “/” und “/boot”

Aktiviät auf der funktionierenden Instanz, nach restore und “apt --reinstall install postgresql-14”:

<user>@<host>:~ $ apt-file search libicui18n
libicu-dev: /usr/lib/aarch64-linux-gnu/libicui18n.a
libicu-dev: /usr/lib/aarch64-linux-gnu/libicui18n.so
libicu67: /usr/lib/aarch64-linux-gnu/libicui18n.so.67
libicu67: /usr/lib/aarch64-linux-gnu/libicui18n.so.67.1

Für “libicui18n.so.63”, das im Log erwähnt wird, kann ich keine Referenz finden.

seufz Nein.

Wenn es um ein Gesamt-Restore geht genügt es normalerweise, den Dump in irgendeine funktionierende, also auch die bestehende Instanz, einzulesen. Entweder per pg_restore oder wenn der Dump im SQL-Format vorliegt auch per psql. Allerdings muß die Datenbankversion identisch sein sonst muß man evtl. Anpassungen vornehmen.

Auch ein partieller Restore ist prinzipiell möglich, indem man sich die entsprechenden Teile aus einem SQL-Dump klaubt und dann in psql füttert. Allerdings ist das meist nicht so wirklich sinnvoll.

Die “klassische” Methode zur Sicherung von Datenbanken ist die inkrementelle Sicherung. dazu macht man zunächst einen Dump und sichert ab da regelmäßig die Transaction Logs. Beim restore wird erst der Dump zurückgelesen und dann die Transaktionen anhand des Transaction Log bis zum gewünschten Zeitunkt nachgefahren. So kann man den Stand zu jedem beliebigen Zeitpunkt wiederherstellen, man muß im Prinzip einfach nur die Logs entsprechend abschneiden.

Heutzutage nimmt man wenn man sowas braucht allerdings lieber point in time Recovery, wenns die Datenbank unterstüzt. Das ist ganz grob gesagt ungefähr das gleiche in Grün, nur “rückwärts”.

Siehe PostgreSQL: Documentation: 14: 26.3. Continuous Archiving and Point-in-Time Recovery (PITR)

Tablespaces im Filesystem zu sichern/zu restoren hat eigentlich nur Nachteile: die Sicherung wird riesengroß weil man Indexe und unused pages mitsichert, es gibt keine Möglichkeit zum partial Restore und man sollte das auch nur tun während das RDBMS runtergefahren wurde und die Sicherung kann nur auf einem exakt identischen System restored werden. Das willst Du nicht tun.

Sinnvoll ist, entweder pg_dumpall/pg_restore zu benutzen oder WAL Archiving. Außer Du hast eine so dermaßen große Transaktionslast daß der Restore auf dem Weg unmöglich wäre, dann brauchst Du aber eigentlich eh ein Cluster.

Danke @eschwenk

In der Doku ist explizit ein Verfahren beschrieben für rsync. Das Verfahren von “raspiBackup” entspricht zwar diesen Anforderungen nicht, aber meinen durchaus. Ich benutze Postgresql als DB für Nextcloud zu privaten Zwecken. Bisher bin ich der einzige Nutzer und kann deshalb die DB wie gewünscht für die ganze Dauer des Backups (z.Z. ca. 30min) stilllegen. Das wird auch noch möglich sein, wenn meine Frau oder ein paar Freunde als Nutzer dazukommen.
Ich kann nachvollziehen, dass für hoch verfügbare Instanzen andere Verfahren gewählt werden müssten. Bei mir wird es aber kaum je so weit kommen.

Um beim Verfahren mit “rsync” bleiben zu können, würde ich zur Not sogar nach dem Restore den Aufruf von “apt --reinstall install postgresql-14” in Kauf nehmen. Wäre aber schön, wenn es auch ohne gehen würde.

Das geht nur, wenn du den PostgreSQL-Server herunterfährst. Steht auch so in der Dokumentation drinnen:

The database server must be shut down in order to get a usable backup.

Dann sollte auch rsync gehen - was ich selbst schon beim Umzug auf andere Server gemacht habe. ABER man muss natürlich darauf achten, dass auch die Berechtigungen etc. alles danach noch stimmen. Sonst knallt es.

Auch persönlicher Erfahrung kann ich dir sagen: mach nen Dump und gut ists. Das macht weniger Probleme, erzeugt keine Ausfälle und ist einfach unproblematischer. Auch kannst du das von extern machen und einfach anskripten.

cu tb

Das klappt aber nur wenn der andere Server das gleiche Betriebssystem (und Architektur) hat.

Wegen diverser Probleme mit unterschiedlichen glibc Versione, muss man dann auf jeden Fall ein reindex auf alle Indizes machen die varchar oder text Spalten enthalten.

Mehr Details hier: Locale data changes - PostgreSQL wiki

Stimmt. Ich habe immer auf die gleiche Basis umgezogen bzw. ganze Server kopiert…

Vielen Dank für die Unterstützung @Xandrian und @castorp

Ich bin Laie und mit meinem Latein rasch mal am Ende, wenn etwas nicht funktioniert, wie z.B. der Pi nicht startet oder die Cloud nicht hochkommt. In solchen Fällen lege ich jeweils den Pi still, schliesse die USB-SSD mit den Partitionen “/” und “/boot” an mein Notebook an und stelle die beiden Partitionen mit dem letzten als funktionierend bekannten Backup auf der SSD wieder her. Ich weiss, dass es mit Risiken verbunden ist, weil in diesem Fall das OS für Backup (RPi OS) und Restore (Mint) nicht das gleiche ist. Damit konnte ich bisher umgehen. Aber was soll ich tun, wenn der Pi nicht mehr startet. Ich habe kein identisches Ersatzgerät. Im Zusammenhang mit dem Pi ändert dabei nichts.
Danach die SSD wieder am Pi anschliessen und starten, eine ssh-Sitzung öffnen, die Dienste, die vor dem Backup stillgelegt wurden (z.B. postgresql) wieder starten und gut ist.

Unter Buster hat das bisher einwandfrei funktioniert. Ich möchte z.Z. nur herausfinden, was ich tun muss um unter Bullseye nach dem Restore die Notwendigkeit eines Reinstalls von Postgresql zu vermeiden. Dies ist im Moment leider nötig, weil es sonst nicht hochkommt:

/usr/lib/postgresql/14/bin/postgres: error while loading shared libraries: libicui18n.so.63: cannot open shared object file: No such file or directory
no data was returned by command ""/usr/lib/postgresql/14/bin/postgres" -V"
The program "postgres" is needed by pg_ctl but was not found in the
same directory as "/usr/lib/postgresql/14/bin/pg_ctl".
Check your installation.

PS: Ich weiss auch, dass ich für den Restore den Pi mit einem frisch installierten RPi OS auf SD starten könnte und somit die Unwägbarkeiten bezüglich unterschiedlicher Plattformen umgehen könnte. Falls ich mein oben beschriebenes Verfahren nicht hinkriege, werde ich mal prüfen, ob sich damit etwas ändert.

Sowas ist für eine Datenbank wie PostgreSQL gibt, böse, und argh.

Warum? Bei deiner Sicherung war die Datenbank in Betrieb. Das heißt die Stände sind nicht sauber. Dazu kommt, das sich eventuell durch Updates irgendwas im System geändert hat. => nicht machen.

Bau dein Backup-Skript um, dass es hier einen Dump zieht und wenn sowas passiert dann spiel den Dump zurück. Spart dir viel Kummer und Ärger und geht auch mit großen Datenbanken problemlos.