Po dlouhou dobu se přidávání balíčků do linuxových systémů odvozených od RedHatu z dobrého důvodu nazývalo „RPM Hell“. Zejména předtím, než se utilita yum objevila na pomoc, bylo přimět RPM, aby dělalo správnou věc, často obtížným úkolem. Dnes jsem si to znovu připomněl, když jsem se pokoušel zkompilovat rozšíření PostgreSQL na dvou téměř identických systémech CentOS.
PostgreSQL poskytuje API s názvem PGXS, které vám umožňuje vytvářet serverová rozšíření, která využívají knihovnu kódu serveru a komunikují s ním. K instalaci našeho nástroje repmgr používáme PGXS a díky tomuto dobře definovanému API lze program vyvíjet externě z hlavního jádra serveru. Mnoho populárních doplňků PostgreSQL se spoléhá na PGXS, aby se vytvořily. Ve skutečnosti příspěvek moduly, které přicházejí se samotným PostgreSQL, jsou často postaveny tímto způsobem. Chytání podobného příspěvku modul a jeho hackování odtud je dobře prošlapaná cesta k vytvoření nového rozšíření PostgreSQL.
PGXS spoléhá na pg_config nástroj je ve vaší PATH. pg_config přichází s balíčkem postgresql-devel, který se dnes ve skutečnosti jmenuje postgresql90-devel . Bohužel ve výchozím nastavení není v cestě nikomu. Takže první krok, který musíte vytvořit pomocí PGXS, je udělat to tam. Něco takového bude fungovat pro většinu systémů UNIX:
Zde je návod, jak sestavení repmgr vypadalo na pracovním systému:
To zahrnuje –m64 -mtune=generic , což jsou možnosti gcc, které říkají sestavení pro 64bitovou platformu, ale nechte kompilátor, aby přesně zjistil, na které z nich se nacházíte, vzhledem k ostatním omezením. V dnešní době je výsledek normálně optimalizovaný pro x86_64, pokud máte 64bitový systém. Automatická detekce byla užitečnější, když byly možnosti i386, i468, i586 a i686.
Do problematického systému. Myslel jsem, že sem dám PostgreSQL stejně, ale sestavení vůbec nefungovalo:
Co? Toto se pokouší vytvořit 32bitový kód: „-m32 -march=i386 -mtune=generic“. Z tohoto důvodu, když se pokusí propojit se všemi 64bitovými knihovnami na serveru, jako je libpq a libtermcap, nemůže. Jak se to proboha děje?
Pomocí pg_config můžete zjistit, odkud pocházejí informace, které se vkládají do příkazu sestavení PGXS . Zde je návod, jak zkontrolovat část související s CFLAGS , část, kde jsou informace o bitové velikosti umístěny na adrese:
Teď jsem naštvaná. To říká, že sestavení je také pro 64 bitů, ale stále nachází 32bitové informace. Odkud to pochází?
Nějaké kopání do rozhraní PGXS, které se snažilo toto zpětně vysledovat, mi nakonec umožnilo přejít na /usr/pgsql-9.0/lib/pgxs/src/Makefile.global a tady je to, co se začalo ukazovat. To soubor uvedené možnosti 32bitového kompilátoru! Odkud se vzali?
V tuto chvíli jsem začal přesně zkoumat, jaké RPM byly na každém serveru nainstalovány,
protože mezi nimi muselo být něco jiného. Zde je užitečný příkaz:
RHEL5 je schopen spouštět 32 i 64bitové aplikace vedle sebe, jen si musíte dát pozor na jejich kompilaci. Je tedy normální, že balíčky pro kompatibilitu databáze compat-postgresql-libs a postgresql90-libs zahrnují obě architektury. Můžete mít aplikace 32 i 64, které chtějí mluvit se stejným serverem. To je často nepříjemné, například když chcete smazat balíček a váš požadavek se shoduje s více než jedním a nedělá nic – potřebujete –allmatches to opravit.
Co vidíme na serveru, který se nezkompiluje? Není to úplně to samé:
Co jsou postgresql90-devel dělají tam balíčky pro i386 i x86_64? To nedává vůbec žádný smysl!
Nyní, po otestování a pokusu o pochopení toho, pokud máte buď balíček -devel a pokusíte se nainstalovat druhý, spustí se správná série chyb u souborů, které jsou v konfliktu, jako je tento:
Balíčkovač dobře ví, že přepisují stejný Makefile.global. Jak jsem skončil s oběma? Po vymazání všeho jsem zjistil přesně jak:
Určitě to není v pořádku! yum je naprosto rád, že je kombinuje, a musel jsem to udělat, aniž bych si toho předtím všiml. Ukazuje se, že pokud je necháte oba nainstalovat takto, kopie, která vám zůstane, nemusí hlásit správné informace zpět do PGXS – nepřekvapivě je zmatená. Tak jsem se svým problémem skončil. Používal jsem Makefile.global nainstalována verzí i386, ale vše ostatní v systému bylo x86_64.
Jak tedy na úklid? Vzhledem k tomu, že zde existuje směs souborů, nemůžete opravdu věřit, že stačí smazat ten nechtěný. Pak vám možná nezůstanou žádné kopie všeho, co se shodovalo. Jedinou bezpečnou volbou je vybuchovat oba, pak stačí nainstalovat ten x86_64, nyní, když přesně víme, že je k dispozici verze z výše uvedeného testu:
Když je toto vyřešeno, moje rozšíření PGXS se nyní staví v pořádku a vývoj
na repmgr pokračuje znovu, po dni ztraceného času na to všechno přijít na to.
Poučení pro dnešek: buďte opatrní při instalaci postgresql90-devel balíček přes yum a nedovolte, aby tam dával obě architektury toho souboru. Používejte pouze ten, který odpovídá platformě vašeho hlavního postgresql90 balík. A pokud se pokoušíte vytvořit rozšíření PGXS na systému RHEL/CentOS a uvidíte nekompatibilní přeskakování knihovna, začněte tím, že se podíváte na vývojové balíčky PostgreSQL, které jste nainstalovali.
Tuto konkrétní špatnou kombinaci pravděpodobně zablokujeme budoucími aktualizacemi balíčků PostgreSQL 9.0. Myslel jsem si, že by bylo zajímavé se o to podělit, protože není mnoho dobrých příkladů řešení problémů, jako je tento, na RPM. Jednou jsem napsal jeden nazvaný Instalace PostgreSQL 8.2 RPM na RHEL 5/CentOS 5, který zde probírá některé další pozadí. Ale to byly jednodušší časy, než byly 64bitové platformy populární a než jste mohli nainstalovat více než jednu verzi PostgreSQL přes RPM současně. Znalost správného zaklínadla RPM pro seznam nainstalovaných balíčků s jejich přidruženou architekturou je v dnešní době zásadním trikem, jak se dostat z pekla RPM.