Por muito tempo, adicionar pacotes aos sistemas Linux derivados do RedHat foi chamado de “RPM Hell”, por um bom motivo. Particularmente antes que o utilitário yum surgisse para ajudar, fazer com que o RPM fizesse a coisa certa muitas vezes era uma tarefa problemática. Lembrei disso novamente hoje, enquanto tentava compilar uma extensão do PostgreSQL em dois sistemas CentOS quase idênticos.
O PostgreSQL fornece uma API chamada PGXS que permite criar extensões de servidor que aproveitam a biblioteca de código do servidor e se comunicam com ela. Usamos PGXS para instalar nosso utilitário repmgr, e ter essa API bem definida permite que o programa seja desenvolvido externamente a partir do núcleo do servidor principal. Muitos complementos populares do PostgreSQL dependem do PGXS para serem construídos. Na verdade, a contribuição módulos que vêm com o próprio PostgreSQL geralmente são construídos dessa maneira. Pegando uma contribuição semelhante módulo e hackeá-lo a partir daí é um caminho bem trilhado para a construção de uma nova extensão do PostgreSQL.
O PGXS depende do pg_config utilitário estar em seu PATH. pg_config vem com o pacote postgresql-devel, que atualmente se chama postgresql90-devel . Infelizmente, não está no caminho para ninguém por padrão. Portanto, o primeiro passo que você precisa para construir usando o PGXS é chegar lá. Algo assim funcionará para a maioria dos sistemas UNIX:
Veja como a construção do repmgr ficou no sistema de trabalho:
Isso inclui –m64 -mtune=generic , que são as opções do gcc para dizer construir para uma plataforma de 64 bits, mas deixe o compilador descobrir exatamente em qual você está em relação às outras restrições. Hoje em dia o resultado normalmente sai otimizado para x86_64 se você tiver um sistema de 64 bits. A detecção automática era mais útil quando as opções eram i386, i468, i586 e i686.
Para o sistema problemático. Eu pensei em colocar o PostgreSQL aqui de forma idêntica, mas a compilação não funcionou:
Que? Isso está tentando construir um código de 32 bits: “-m32 -march=i386 -mtune=generic”. Por causa disso, quando tenta se conectar com todas as bibliotecas de 64 bits no servidor, como libpq e libtermcap, não consegue. Como no mundo isso está acontecendo?
Você pode ver de onde vêm as informações que entram em um comando de compilação PGXS usando pg_config . Veja como verificar a parte relacionada às CFLAGS , a seção em que as informações de tamanho de bits estão localizadas:
Agora estou chateado. Isso está dizendo construir para 64 bits também, mas ainda está encontrando informações de 32 bits. De onde aquilo está vindo?
Algumas pesquisas na interface PGXS tentando rastrear isso eventualmente me permitiram /usr/pgsql-9.0/lib/pgxs/src/Makefile.global e aqui está o que a pista começou a aparecer. Isso arquivo listado opções do compilador de 32 bits! De onde eles vieram?
Nesse ponto, comecei a ver exatamente quais RPMs estavam instalados em cada servidor,
porque algo tinha que ser diferente entre eles. Aqui está um comando útil para saber:
O RHEL5 é capaz de executar aplicativos de 32 e 64 bits lado a lado, basta ter cuidado para compilá-los. Portanto, é normal que os pacotes de compatibilidade do banco de dados compat-postgresql-libs e postgresql90-libs incluem ambas as arquiteturas. Você pode ter 32 e 64 aplicativos que desejam se comunicar com o mesmo servidor. Isso geralmente é irritante, por exemplo, quando você deseja excluir um pacote e ele informa que sua solicitação corresponde a mais de um e não faz nada – você precisa de –allmatches para consertar isso.
O que vemos no servidor que não compila? Não 'e a mesma coisa:
O que são postgresql90-devel pacotes para i386 e x86_64 fazendo lá? Isso não faz o menor sentido!
Agora, depois de testar para tentar entender isso, se você tiver um dos pacotes -devel e tentar instalar o outro, ele retornará a série correta de erros para arquivos em conflito, como este:
O empacotador sabe perfeitamente que eles sobrescrevem o mesmo Makefile.global. Como eu terminei com os dois? Depois de limpar tudo, descobri exatamente como:
Certamente não está bem! yum está perfeitamente feliz em combiná-los, e devo ter feito isso sem perceber antes. Acontece que, se você permitir que ambos sejam instalados assim, a cópia que resta pode não relatar as informações corretas de volta ao PGXS - sem surpresa, é confuso. Foi assim que acabei com o meu problema. Eu estava usando o Makefile.global instalado pela versão i386, mas todo o resto no sistema era x86_64.
Então, como limpar? Dada a mistura de arquivos aqui, você não pode realmente confiar que apenas excluir o indesejado é suficiente. Então você pode não ter mais cópias de tudo que conflciou. A única escolha segura é destruir os dois, então basta instalar o x86_64, agora que sabemos exatamente que a versão está disponível no teste acima:
Com isso resolvido, agora minha extensão PGXS é construída bem, e o desenvolvimento
no repmgr continua novamente, após um dia de tempo perdido para descobrir tudo isso.
Lições para hoje: tenha cuidado ao instalar o postgresql90-devel package via yum e não deixe que ele coloque as duas arquiteturas desse arquivo lá. Use apenas aquele que corresponde à plataforma do seu postgresql90 principal pacote. E se você está tentando construir uma extensão PGXS em um sistema RHEL/CentOS, e você vê o ignorando incompatível library, comece examinando o(s) pacote(s) de desenvolvimento do PostgreSQL que você instalou.
Provavelmente, essa combinação ruim específica será bloqueada por futuras atualizações dos pacotes do PostgreSQL 9.0. Achei interessante compartilhar de qualquer maneira, porque não há muitos bons exemplos de solução de problemas como esse no RPM. Certa vez escrevi um intitulado Instalando os RPMs do PostgreSQL 8.2 no RHEL 5/CentOS 5 que aborda um pouco mais dos antecedentes aqui. Mas aqueles eram dias mais simples, antes que as plataformas de 64 bits fossem populares e antes que você pudesse instalar mais de uma versão do PostgreSQL via RPM ao mesmo tempo. Conhecer o encantamento RPM correto para listar os pacotes instalados com sua arquitetura associada é um truque vital hoje em dia para sair do inferno do RPM.