Durante mucho tiempo, agregar paquetes a los sistemas Linux derivados de RedHat se ha llamado "RPM Hell", por una buena razón. Particularmente antes de que la utilidad yum apareciera para ayudar, lograr que RPM hiciera lo correcto a menudo ha sido una tarea problemática. Volví a recordar esto hoy, mientras intentaba compilar una extensión de PostgreSQL en dos sistemas CentOS casi idénticos.
PostgreSQL proporciona una API denominada PGXS que le permite crear extensiones de servidor que aprovechan la biblioteca de código del servidor y se comunican con él. Usamos PGXS para instalar nuestra utilidad repmgr, y tener esa API bien definida permite que el programa se desarrolle externamente desde el núcleo del servidor principal. Muchas piezas populares de complementos de PostgreSQL dependen de PGXS para construirse. De hecho, la contrib los módulos que vienen con PostgreSQL a menudo se construyen de esta manera. Tomando una contrib similar módulo y piratearlo desde allí es un camino bien recorrido para construir una nueva extensión de PostgreSQL.
PGXS se basa en pg_config la utilidad está en su RUTA. pg_config viene con el paquete postgresql-devel, que actualmente se llama postgresql90-devel . Desafortunadamente, no está en el camino para nadie por defecto. Entonces, el primer paso que necesita para construir usando PGXS es hacerlo allí. Algo como esto funcionará para la mayoría de los sistemas UNIX:
Así es como se veía la construcción de repmgr en el sistema de trabajo:
Esto incluye –m64 -mtune=generic , que son las opciones de gcc para decir compilar para una plataforma de 64 bits, pero deje que el compilador descubra exactamente en cuál se encuentra en relación con las otras restricciones. Hoy en día el resultado normalmente sale optimizado para x86_64 si tienes un sistema de 64 bits. La detección automática fue más útil cuando las opciones eran i386, i468, i586 e i686.
En el sistema problemático. Pensé en poner PostgreSQL aquí de forma idéntica, pero la compilación no funcionó en absoluto:
¿Qué? Esto está intentando compilar un código de 32 bits:"-m32 -march=i386 -mtune=generic". Por eso, cuando intenta vincularse con todas las bibliotecas de 64 bits en el servidor como libpq y libtermcap, no puede. ¿Cómo diablos está pasando esto?
Puede ver de dónde proviene la información que se incluye en un comando de compilación PGXS usando pg_config . Aquí se explica cómo verificar la parte relacionada con CFLAGS , la sección donde se encuentra la información del tamaño de bit en:
Ahora estoy enojado. Esto también dice compilación para 64 bits, pero todavía está encontrando información de 32 bits. ¿De dónde viene eso?
Algunas excavaciones en la interfaz PGXS tratando de rastrear esto finalmente me permitieron /usr/pgsql-9.0/lib/pgxs/src/Makefile.global y esto es lo que la pista comenzó a aparecer. Eso ¡El archivo enumera las opciones del compilador de 32 bits! ¿De dónde vienen?
En este punto, comencé a ver exactamente qué RPM estaban instalados en cada servidor,
porque algo tenía que ser diferente entre ellos. Aquí hay un comando útil para saber:
RHEL5 es capaz de ejecutar aplicaciones de 32 y 64 bits en paralelo, solo debe tener cuidado al compilarlas. Por lo tanto, es normal que los paquetes de compatibilidad de bases de datos compat-postgresql-libs y postgresql90-libs incluyen ambas arquitecturas. Es posible que tenga aplicaciones 32 y 64 que quieran comunicarse con el mismo servidor. Esto suele ser molesto, por ejemplo, cuando desea eliminar un paquete y le dice que su solicitud coincide con más de uno y no hace nada:necesita –allmatches para arreglar eso.
¿Qué vemos en el servidor que no compila? No es lo mismo:
¿Qué son postgresql90-devel paquetes para i386 y x86_64 haciendo allí? ¡Eso no tiene ningún sentido!
Ahora, después de probar para tratar de dar sentido a esto, si tiene el paquete -devel e intenta instalar el otro, se devuelve la serie correcta de errores para los archivos en conflicto, como este:
El empaquetador sabe perfectamente que sobrescriben el mismo Makefile.global. ¿Cómo terminé con ambos? Después de borrar todo, encontré exactamente cómo:
¡Ciertamente no está bien! yum está perfectamente feliz de combinarlos, y debo haberlo hecho sin darme cuenta antes. Resulta que si permite que ambos se instalen así, es posible que la copia que le quede no proporcione la información correcta a PGXS; como era de esperar, está confundida. Así es como terminé con mi problema. Estaba usando Makefile.global instalado por la versión i386, pero todo lo demás en el sistema era x86_64.
Entonces, ¿cómo limpiar? Dada la combinación de archivos aquí, realmente no puede confiar en que solo eliminar el no deseado es suficiente. Entonces es posible que no le queden copias de todo lo que conflcó. La única opción segura es bombardearlos a ambos, luego simplemente instalar el x86_64, ahora que sabemos que la versión exacta está disponible en la prueba anterior:
Con esto solucionado, ahora mi extensión PGXS se compila correctamente y el desarrollo
en repmgr continúa, después de un día de tiempo perdido para resolver todo esto.
Lecciones para hoy:tenga cuidado al instalar postgresql90-devel paquete a través de yum, y no permita que coloque ambas arquitecturas de ese archivo allí. Solo use el que coincida con la plataforma de su principal postgresql90 paquete. Y si está intentando crear una extensión PGXS en un sistema RHEL/CentOS, y ve el salto incompatible mensaje de la biblioteca, comience mirando los paquetes de desarrollo de PostgreSQL que ha instalado.
Probablemente obtendremos esta mala combinación particular bloqueada por futuras actualizaciones de los paquetes de PostgreSQL 9.0. Pensé que era interesante compartirlo de todos modos, porque no hay muchos buenos ejemplos de solución de problemas como este en RPM. Una vez escribí uno titulado Instalación de los RPM de PostgreSQL 8.2 en RHEL 5/CentOS 5 que analiza un poco más los antecedentes aquí. Pero esos eran días más simples, antes de que las plataformas de 64 bits fueran populares y antes de que pudieras instalar más de una versión de PostgreSQL a través de RPM al mismo tiempo. Saber el conjuro correcto de RPM para enumerar los paquetes instalados con su arquitectura asociada es un truco vital hoy en día para salir del infierno de RPM.