Das Hinzufügen von Paketen zu von RedHat abgeleiteten Linux-Systemen wurde lange Zeit aus gutem Grund als „RPM-Hölle“ bezeichnet. Besonders bevor das Yum-Hilfsprogramm zu Hilfe kam, war es oft eine mühsame Aufgabe, RPM dazu zu bringen, das Richtige zu tun. Daran wurde ich heute wieder erinnert, als ich versuchte, eine PostgreSQL-Erweiterung auf zwei nahezu identischen CentOS-Systemen zu kompilieren.
PostgreSQL stellt eine API namens PGXS bereit, mit der Sie Servererweiterungen erstellen können, die sowohl die Codebibliothek des Servers nutzen als auch damit kommunizieren. Wir verwenden PGXS, um unser Dienstprogramm repmgr zu installieren, und mit dieser gut definierten API kann das Programm extern vom Hauptserverkern entwickelt werden. Viele beliebte Teile von PostgreSQL-Add-Ons verlassen sich auf PGXS, um sich selbst zu erstellen. Tatsächlich ist der Beitrag Module, die mit PostgreSQL selbst geliefert werden, werden oft auf diese Weise erstellt. Holen Sie sich einen ähnlichen Beitrag Modul und von dort aus darauf zu hacken, ist ein ausgetretener Weg zum Erstellen einer neuen PostgreSQL-Erweiterung.
PGXS stützt sich auf die pg_config Dienstprogramm in Ihrem PATH. pg_config kommt mit dem Paket postgresql-devel, das heutzutage eigentlich postgresql90-devel heißt . Leider ist es standardmäßig für niemanden im Pfad. Der erste Schritt, den Sie zum Erstellen mit PGXS benötigen, ist also, es dorthin zu schaffen. So etwas funktioniert für die meisten UNIX-Systeme:
So sah das Erstellen von repmgr auf dem funktionierenden System aus:
Dazu gehört –m64 -mtune=generic , das sind die gcc-Optionen, um zu sagen, dass Sie für eine 64-Bit-Plattform bauen, aber lassen Sie den Compiler genau herausfinden, auf welcher Sie sich im Verhältnis zu den anderen Einschränkungen befinden. Heutzutage ist das Ergebnis normalerweise für x86_64 optimiert, wenn Sie ein 64-Bit-System haben. Die automatische Erkennung war früher nützlicher, als die Auswahlmöglichkeiten i386, i468, i586 und i686 waren.
Auf das problematische System. Ich dachte, ich würde PostgreSQL hier identisch installieren, aber der Build funktionierte überhaupt nicht:
Was? Hier wird versucht, 32-Bit-Code zu erstellen:„-m32 -march=i386 -mtune=generic“. Wenn es versucht, eine Verbindung mit allen 64-Bit-Bibliotheken auf dem Server wie libpq und libtermcap herzustellen, ist dies daher nicht möglich. Wie um alles in der Welt passiert das?
Mit pg_config können Sie sehen, woher die Informationen kommen, die in einen PGXS-Build-Befehl einfließen . So überprüfen Sie den Teil, der sich auf die CFLAGS bezieht , der Abschnitt, in dem sich die Informationen zur Bitgröße befinden:
Jetzt bin ich sauer. Dies bedeutet, dass auch für 64 Bit gebaut wird, aber es werden immer noch 32-Bit-Informationen gefunden. Woher kommt das?
Einige Recherchen in der PGXS-Schnittstelle, die versuchten, dies zurückzuverfolgen, führten mich schließlich zu /usr/pgsql-9.0/lib/pgxs/src/Makefile.global und hier ist, was der Hinweis zu zeigen begann. Das Datei aufgeführte 32-Bit-Compiler-Optionen! Woher kamen sie?
An diesem Punkt fing ich an, mir genau anzusehen, welche RPMs auf jedem Server installiert waren,
weil irgendetwas zwischen ihnen unterschiedlich sein musste. Hier ist ein praktischer Befehl, den Sie kennen sollten:
RHEL5 kann 32- und 64-Bit-Anwendungen nebeneinander ausführen, Sie müssen nur darauf achten, sie zu kompilieren. Daher ist es normal, dass die Datenbankkompatibilitätspakete compat-postgresql-libs enthalten und postgresql90-libs beide Architekturen umfassen. Möglicherweise haben Sie sowohl 32 als auch 64 Apps, die mit demselben Server kommunizieren möchten. Dies ist oft ärgerlich, wenn Sie zum Beispiel ein Paket löschen möchten und Ihre Anfrage mit mehr als einem übereinstimmt und nichts tut – Sie brauchen –allmatches um das zu beheben.
Was sehen wir auf dem Server, das nicht kompiliert wird? Nicht ganz dasselbe:
Was sind postgresql90-devel Pakete für i386 und x86_64 dort tun? Das macht überhaupt keinen Sinn!
Nun, nachdem Sie versucht haben, dies zu verstehen, wenn Sie eines der -devel-Pakete haben und versuchen, das andere zu installieren, wird die richtige Reihe von Fehlern für Dateien zurückgeworfen, die Konflikte verursachen, wie hier:
Der Paketierer weiß ganz genau, dass er dasselbe Makefile.global überschreibt. Wie endete ich mit beiden? Nachdem ich alles gelöscht hatte, fand ich genau wie:
Es ist sicherlich nicht in Ordnung! yum ist vollkommen glücklich, sie zu kombinieren, und ich muss das getan haben, ohne es vorher zu bemerken. Es stellt sich heraus, dass, wenn Sie sie beide so installieren lassen, die Kopie, die Ihnen bleibt, möglicherweise nicht die richtigen Informationen an PGXS zurückmeldet – es überrascht nicht, dass sie verwirrt ist. So bin ich bei meinem Problem gelandet. Ich habe die Makefile.global verwendet von der i386-Version installiert, aber alles andere auf dem System war x86_64.
Wie also aufräumen? Angesichts der Mischung von Dateien hier können Sie nicht wirklich darauf vertrauen, dass es ausreicht, nur die unerwünschte Datei zu löschen. Dann haben Sie vielleicht keine Kopien mehr von allem, was widersprüchlich ist. Die einzige sichere Wahl ist, sie beide zu nuklearisieren und dann einfach die x86_64-Version zu installieren, jetzt, wo wir genau wissen, dass die Version aus dem obigen Test verfügbar ist:
Nachdem dies geklärt ist, lässt sich meine PGXS-Erweiterung jetzt problemlos erstellen, und die Entwicklung
auf repmgr wird wieder fortgesetzt, nach einem Tag verlorener Zeit, um dies alles herauszufinden.
Lektionen für heute:Seien Sie vorsichtig bei der Installation von postgresql90-devel Paket über yum, und lassen Sie es nicht beide Architekturen dieser Datei dort ablegen. Verwenden Sie nur diejenige, die der Plattform Ihres Haupt-postgresql90 entspricht Paket. Und wenn Sie versuchen, eine PGXS-Erweiterung auf einem RHEL/CentOS-System zu erstellen, und Sie das Überspringen inkompatibel sehen Bibliotheksnachricht, sehen Sie sich zunächst die PostgreSQL-Entwicklungspakete an, die Sie installiert haben.
Wir werden diese spezielle schlechte Kombination wahrscheinlich durch zukünftige Updates der PostgreSQL 9.0-Pakete blockieren. Ich fand es trotzdem interessant, es zu teilen, da es nicht viele gute Beispiele für eine solche Fehlerbehebung bei RPM gibt. Ich habe einmal einen Artikel mit dem Titel Installing the PostgreSQL 8.2 RPMs on RHEL 5/CentOS 5 geschrieben, der hier einige weitere Hintergrundinformationen enthält. Aber das waren einfachere Zeiten, bevor 64-Bit-Plattformen populär wurden und bevor Sie mehr als eine PostgreSQL-Version gleichzeitig über RPM installieren konnten. Die richtige RPM-Beschwörung zu kennen, um installierte Pakete mit ihrer zugehörigen Architektur aufzulisten, ist heutzutage ein entscheidender Trick, um aus der RPM-Hölle herauszukommen.