sql >> Database >  >> RDS >> PostgreSQL

Hoe PostgreSQL 9.0-extensies niet te bouwen op RPM-platforms

Lange tijd werd het toevoegen van pakketten aan van RedHat afgeleide Linux-systemen niet voor niets "RPM Hell" genoemd. Vooral voordat het hulpprogramma yum kwam om te helpen, was het vaak een lastige taak om RPM het juiste te laten doen. Ik werd hier vandaag weer aan herinnerd, terwijl ik probeerde een PostgreSQL-extensie te compileren op twee bijna identieke CentOS-systemen.

PostgreSQL biedt een API met de naam PGXS waarmee u serverextensies kunt bouwen die zowel gebruikmaken van de codebibliotheek van de server als ermee communiceren. We gebruiken PGXS om ons repmgr-hulpprogramma te installeren en met die goed gedefinieerde API kan het programma extern worden ontwikkeld vanuit de hoofdserverkern. Veel populaire PostgreSQL-add-ons vertrouwen op PGXS om zichzelf te bouwen. In feite is de bijdrage modules die bij PostgreSQL zelf worden geleverd, zijn vaak op deze manier gebouwd. Een soortgelijke bijdrage . pakken module en vanaf daar te hacken is een goed betreden pad naar het bouwen van een nieuwe PostgreSQL-extensie.

PGXS vertrouwt op de pg_config hulpprogramma dat zich in uw PATH bevindt. pg_config wordt geleverd met het pakket postgresql-devel, dat tegenwoordig eigenlijk postgresql90-devel heet . Helaas staat het standaard voor niemand op het pad. Dus de eerste stap die u moet bouwen met PGXS, is om het daar te maken. Iets als dit werkt voor de meeste UNIX-systemen:

Zo zag het bouwen van repmgr eruit op het werkende systeem:

Dit omvat –m64 -mtune=generic , wat de gcc-opties zijn om te zeggen gebouwd voor een 64-bits platform, maar laat de compiler precies uitzoeken op welke u zich bevindt ten opzichte van de andere beperkingen. Tegenwoordig is het resultaat normaal gesproken geoptimaliseerd voor x86_64 als je een 64-bits systeem hebt. De automatische detectie was nuttiger toen de keuzes i386, i468, i586 en i686 waren.

Op naar het lastige systeem. Ik dacht dat ik PostgreSQL hier op dezelfde manier zou plaatsen, maar de build werkte helemaal niet:

Wat? Dit probeert 32-bits code te bouwen:  "-m32 -march=i386 -mtune=generic". Daarom kan het, wanneer het probeert te linken met alle 64-bits bibliotheken op de server zoals libpq en libtermcap, dat niet. Hoe gebeurt dit in hemelsnaam?

Met pg_config kunt u zien waar de informatie die in een PGXS-buildopdracht gaat, vandaan komt . U kunt als volgt het gedeelte controleren dat verband houdt met de CFLAGS , het gedeelte waar de informatie over de bitgrootte zich bevindt:

Nu ben ik boos. Dit zegt ook build voor 64 bits, maar het vindt nog steeds 32-bits informatie. Waar komt dat vandaan?

Na enig graven in de PGXS-interface om dit terug te traceren, kwam ik uiteindelijk op /usr/pgsql-9.0/lib/pgxs/src/Makefile.global en hier is wat de aanwijzing begon te verschijnen. Dat bestand vermeld 32-bits compiler-opties! Waar kwamen ze vandaan?

Op dit punt begon ik precies te kijken welke RPM's op elke server waren geïnstalleerd,
omdat er iets anders moest zijn tussen hen. Hier is een handig commando om te weten:

RHEL5 kan 32- en 64-bits applicaties naast elkaar draaien, u moet alleen voorzichtig zijn om ze te compileren. Het is dus normaal dat de databasecompatibiliteitspakketten compat-postgresql-libs en postgresql90-libs beide architecturen omvatten. Mogelijk hebt u zowel 32 als 64 apps die met dezelfde server willen praten. Dit is vaak vervelend, bijvoorbeeld wanneer u een pakket wilt verwijderen en het vertelt uw verzoek komt overeen met meer dan één en doet niets – u hebt –allmatches nodig om dat op te lossen.

Wat zien we op de server die niet compileert? Niet helemaal hetzelfde:

Wat zijn postgresql90-devel pakketten voor zowel i386 als x86_64 doen daar? Dat slaat helemaal nergens op!

Nu, na het testen om te proberen dit te begrijpen, als je een van de -devel-pakketten hebt en de andere probeert te installeren, wordt de juiste reeks fouten teruggezet voor bestanden die conflicteren, zoals deze:

De verpakker weet heel goed dat ze dezelfde Makefile.global overschrijven. Hoe ben ik met beide geëindigd? Nadat ik alles had weggevaagd, ontdekte ik precies hoe:

Het is zeker niet oké! yum is perfect blij om ze te combineren, en dat moet ik gedaan hebben zonder het eerder te merken. Het blijkt dat als je ze allebei op deze manier laat installeren, de kopie die je overhoudt mogelijk niet de juiste informatie teruggeeft aan PGXS - het is niet verwonderlijk dat het in de war is. Zo kwam ik bij mijn probleem. Ik gebruikte de Makefile.global geïnstalleerd door de i386-versie, maar al het andere op het systeem was x86_64.

Dus hoe opruimen? Gezien de mix van bestanden hier, kun je er niet echt op vertrouwen dat alleen het verwijderen van de ongewenste voldoende is. Dan heb je misschien geen kopieën meer van alles wat in strijd was. De enige veilige keuze is om ze allebei te vernietigen, en dan gewoon de x86_64 te installeren, nu we precies weten dat de versie beschikbaar is uit de bovenstaande test:

Nu dit is opgelost, bouwt mijn PGXS-extensie nu prima en de ontwikkeling
op repmgr gaat weer door, na een dag verloren tijd om dit allemaal uit te zoeken.

Lessen voor vandaag:wees voorzichtig bij het installeren van de postgresql90-devel pakket via yum, en laat het niet beide architecturen van dat bestand daar plaatsen. Gebruik alleen degene die overeenkomt met het platform van uw hoofd postgresql90 pakket. En als u een PGXS-extensie probeert te bouwen op een RHEL/CentOS-systeem, en u ziet de incompatibel overslaan bibliotheekbericht, kijk eerst naar de PostgreSQL-ontwikkelpakket(ten) die u hebt geïnstalleerd.

We zullen deze specifieke slechte combinatie waarschijnlijk geblokkeerd krijgen door toekomstige updates van de PostgreSQL 9.0-pakketten. Ik dacht dat het toch interessant was om te delen, omdat er niet veel goede voorbeelden zijn van dit soort troubleshooting op RPM. Ik heb er ooit een geschreven met de titel De PostgreSQL 8.2 RPM's installeren op RHEL 5/CentOS 5 die hier wat meer van de achtergrond doorneemt. Maar dat waren eenvoudiger dagen, voordat 64-bits platforms populair waren en voordat je meer dan één PostgreSQL-versie via RPM tegelijk kon installeren. Het kennen van de juiste RPM-bezwering om pakketten weer te geven die zijn geïnstalleerd met hun bijbehorende architectuur, is tegenwoordig een essentiële truc om uit de RPM-hel te komen.


  1. Rethink Flask - Een eenvoudige takenlijst mogelijk gemaakt door Flask en RethinkDB

  2. UUID-prestaties in MySQL?

  3. Update met parameter met behulp van de permanente bibliotheek van de kamer

  4. Ontbrekende velden corrigeren in een kruistabelquery in Access