Att lägga till paket till RedHat-härledda Linux-system har under lång tid kallats "RPM Hell", av goda skäl. Särskilt innan verktyget yum kom för att hjälpa, har det ofta varit en besvärlig uppgift att få RPM att göra rätt. Jag blev påmind om detta igen idag när jag försökte kompilera en PostgreSQL-tillägg på två nästan identiska CentOS-system.
PostgreSQL tillhandahåller ett API som heter PGXS som låter dig bygga servertillägg som både utnyttjar serverns kodbibliotek och kommunicerar med det. Vi använder PGXS för att installera vårt repmgr-verktyg, och med det väldefinierade API:t låter programmet utvecklas externt från huvudserverns kärna. Många populära delar av PostgreSQL-tillägg förlitar sig på PGXS för att bygga sig själva. Faktum är att bidraget moduler som kommer med själva PostgreSQL är ofta byggda på detta sätt. Får ett liknande bidrag modul och hacka på den därifrån är en bra väg mot att bygga ett nytt PostgreSQL-tillägg.
PGXS förlitar sig på pg_config verktyget är i din PÅGÅNG. pg_config kommer med postgresql-devel-paketet, som numera faktiskt heter postgresql90-devel . Tyvärr är det inte i vägen för någon som standard. Så det första steget du behöver för att bygga med PGXS är att ta dig dit. Något liknande detta kommer att fungera för de flesta UNIX-system:
Så här såg byggnaden repmgr ut på det fungerande systemet:
Detta inkluderar –m64 -mtune=generic , som är gcc-alternativen för att säga bygga för en 64-bitars plattform, men låt kompilatorn ta reda på exakt vilken du är på i förhållande till de andra begränsningarna. Nuförtiden kommer resultatet normalt ut optimerat för x86_64 om du har ett 64-bitarssystem. Den automatiska upptäckten var mer användbar när valen var i386, i468, i586 och i686.
Till det jobbiga systemet. Jag trodde att jag skulle lägga till PostgreSQL här på samma sätt, men bygget fungerade inte alls:
Vad? Detta försöker bygga 32-bitars kod: "-m32 -march=i386 -mtune=generic". På grund av det, när den försöker länka till alla 64-bitars bibliotek på servern som libpq och libtermcap, kan den inte. Hur i hela friden händer detta?
Du kan se var informationen som går in i ett PGXS-byggkommando kommer ifrån med pg_config . Så här kontrollerar du delen som är relaterad till CFLAGS , avsnittet där bitstorleksinformationen finns på:
nu är jag förbannad. Detta säger också att bygga för 64 bitar, men den hittar fortfarande 32-bitars information. Var kommer det ifrån?
En del grävande i PGXS-gränssnittet och försökte spåra detta lät mig så småningom till /usr/pgsql-9.0/lib/pgxs/src/Makefile.global och här är vad ledtråden började dyka upp. Det fil listade 32-bitars kompilatoralternativ! Var kom de ifrån?
Vid det här laget började jag titta på exakt vilka RPM som var installerade på varje server,
eftersom något måste vara annorlunda mellan dem. Här är ett praktiskt kommando att veta:
RHEL5 kan köra 32 och 64 bitars applikationer sida vid sida, du måste bara vara noga med att kompilera dem. Så det är normalt att databaskompatibilitetspaketen compat-postgresql-libs och postgresql90-libs inkluderar båda arkitekturerna. Du kanske har både 32 och 64 appar som vill prata med samma server. Detta är ofta irriterande, till exempel när du vill ta bort ett paket och det säger att din begäran matchar mer än en och inte gör något – du behöver –allmatches för att fixa det.
Vad ser vi på servern som inte kompilerar? Inte riktigt samma sak:
Vad är postgresql90-devel paket för både i386 och x86_64 gör det? Det är ingen mening alls!
Nu, efter att ha testat för att försöka förstå detta, om du har något av -devel-paketet och försöker installera det andra, sparkar det tillbaka den rätta serien av fel för filer som konflikter, så här:
Förpackaren vet mycket väl att de skriver över samma Makefile.global. Hur slutade jag med båda? Efter att ha raderat allt hittade jag exakt hur:
Det är absolut inte OK! yum kombinerar dem gärna, och det måste jag ha gjort utan att ha märkt det innan. Det visar sig att om du låter dem båda installera så här, kanske kopian du har kvar inte rapporterar tillbaka rätt information till PGXS – föga överraskande är den förvirrad. Det var så jag slutade med mitt problem. Jag använde Makefile.global installerat av i386-versionen, men allt annat på systemet var x86_64.
Så hur städar man? Med tanke på mixen av filer här kan du inte riktigt lita på att det räcker att bara ta bort den oönskade. Då kanske du inte har några kopior kvar av allt som stämde. Det enda säkra valet är att kärnvapen dem båda, sedan är det bara att installera x86_64, nu när vi vet exakt är versionen tillgänglig från testet ovan:
Med detta löst, nu bygger mitt PGXS-tillägg bra, och utvecklingen
på repmgr fortsätter igen, efter en dag av förlorad tid för att ta reda på allt detta.
Lärdomar för idag: var försiktig när du installerar postgresql90-devel paketera via yum, och låt det inte placera båda arkitekturerna för den filen där. Använd bara den som matchar plattformen för din huvudsakliga postgresql90 paket. Och om du försöker bygga en PGXS-tillägg på ett RHEL/CentOS-system och du ser hoppningsinkompatibel biblioteksmeddelande, börja med att titta på PostgreSQL-utvecklingspaketet som du har installerat.
Vi kommer förmodligen att blockera den här dåliga kombinationen av framtida uppdateringar av PostgreSQL 9.0-paketen. Jag tyckte det var intressant att dela ändå, för det finns inte många bra exempel på att göra felsökning som denna på RPM. Jag skrev en gång en med titeln Installera PostgreSQL 8.2 RPM på RHEL 5/CentOS 5 som går igenom lite mer av bakgrunden här. Men det var enklare dagar, innan 64-bitarsplattformar var populära, och innan du kunde installera mer än en PostgreSQL-version via RPM samtidigt. Att känna till rätt RPM-besvärjelse för att lista paket installerade med deras tillhörande arkitektur är ett viktigt knep nuförtiden för att navigera dig ut ur RPM-helvetet.