長い間、RedHatから派生したLinuxシステムにパッケージを追加することは、正当な理由から「RPMHell」と呼ばれてきました。特にyumユーティリティが役立つようになる前は、RPMに正しいことをさせることはしばしば厄介な作業でした。ほぼ同一の2つのCentOSシステムでPostgreSQL拡張機能をコンパイルしようとしたときに、今日もこのことを思い出しました。
PostgreSQLは、サーバーのコードライブラリを活用し、サーバーと通信するサーバー拡張機能を構築できるPGXSという名前のAPIを提供します。 PGXSを使用してrepmgrユーティリティをインストールし、その明確に定義されたAPIを使用して、プログラムをメインサーバーコアから外部で開発できるようにします。 PostgreSQLアドオンの多くの人気のある部分は、PGXSに依存して自分自身を構築します。実際、投稿 PostgreSQL自体に付属するモジュールは、多くの場合、この方法で構築されます。同様の投稿を取得する モジュールとそこからのハッキングは、新しいPostgreSQL拡張機能を構築するための十分な道のりです。
PGXSはpg_configに依存しています ユーティリティがPATHに含まれています。 pg_config postgresql-develパッケージが付属しており、現在は実際には postgresql90-develという名前になっています。 。残念ながら、デフォルトでは誰にとってもパスに含まれていません。したがって、PGXSを使用して構築する必要がある最初のステップは、そこに到達することです。このようなものは、ほとんどのUNIXシステムで機能します:
repmgrの構築が動作中のシステムでどのように見えたかを次に示します。
これには– m64 -mtune =generic が含まれます 、これは64ビットプラットフォーム用にビルドするというgccオプションですが、他の制限と比較して、どちらを使用しているかをコンパイラーに正確に認識させます。現在、64ビットシステムを使用している場合、結果は通常x86_64用に最適化されて出力されます。自動検出は、選択肢がi386、i468、i586、およびi686であったときに、より便利でした。
面倒なシステムに。ここにPostgreSQLを同じように配置すると思いましたが、ビルドはまったく機能しませんでした:
何?これは32ビットコードをビルドしようとしています:「-m32 -march =i386 -mtune=generic」。そのため、libpqやlibtermcapなどのサーバー上のすべての64ビットライブラリとリンクしようとしても、リンクできません。これは世界でどのように起こっていますか?
pg_config を使用すると、PGXSビルドコマンドに入力される情報がどこから来ているかを確認できます。 。 CFLAGSに関連する部分を確認する方法は次のとおりです 、ビットサイズ情報が配置されているセクション:
今、私は腹を立てています。これは、64ビット用にビルドすることも言っていますが、それでも32ビット情報を検出しています。それはどこから来たのですか?
これをさかのぼってPGXSインターフェイスを掘り下げてみると、最終的には /usr/pgsql-9.0/lib/pgxs/src/Makefile.globalにたどり着くことができます。 これが手がかりが現れ始めたものです。 それ ファイルにリストされた32ビットコンパイラオプション!彼らはどこから来たのですか?
この時点で、各サーバーにインストールされているRPMを正確に調べ始めました。これは、サーバー間で何かが異なる必要があるためです。
知っておくと便利なコマンドは次のとおりです。
RHEL5は、32ビットと64ビットのアプリケーションを並べて実行できます。コンパイルには注意が必要です。したがって、データベース互換性パッケージが compat-postgresql-libsであるのは正常です。 およびpostgresql90-libs 両方のアーキテクチャが含まれます。同じサーバーと通信したい32と64の両方のアプリがあるかもしれません。これは多くの場合、煩わしいものです。たとえば、パッケージを削除したいときに、リクエストが複数一致し、何も実行しないことが通知された場合、 –allmatchesが必要です。 それを修正します。
コンパイルされないサーバーには何が表示されますか?まったく同じではありません:
postgresql90-develとは i386とx86_64の両方のパッケージがそこで実行されていますか?それはまったく意味がありません!
さて、これを理解するためにテストした後、どちらかの-develパッケージがあり、もう一方をインストールしようとすると、次のように、競合するファイルの正しい一連のエラーがキックバックされます。
パッケージャは、同じMakefile.globalを上書きすることを完全によく知っています。どのように私は両方で終わったのですか?すべてを一掃した後、私は正確にどのように見つけました:
それは確かにOKではありません! yumはそれらを組み合わせるのに完全に満足しています、そして私は前に気付かずにそれをしたに違いありません。両方をこのようにインストールすると、残っているコピーが正しい情報をPGXSに報告しない可能性があります。当然のことながら、混乱します。それが私の問題に終わった方法です。 Makefile.globalを使用していました i386バージョンでインストールされましたが、システム上の他のすべてはx86_64でした。
では、どのようにクリーンアップするのですか?ここにファイルが混在していることを考えると、不要なファイルを削除するだけで十分だとは本当に信じられません。そうすると、矛盾したすべてのコピーが残っていない可能性があります。安全な選択は、両方を削除してから、x86_64をインストールすることです。これで、上記のテストから正確なバージョンが利用可能であることがわかりました。
これが整理されたので、私のPGXS拡張機能は問題なく構築され、
これをすべて理解するために1日の時間を失った後、repmgrでの開発が再び進行します。
今日の教訓: postgresql90-develをインストールするときは注意してください yumを介してパッケージ化し、そのファイルの両方のアーキテクチャをそこに配置しないようにします。メインのpostgresql90のプラットフォームに一致するもののみを使用してください パッケージ。また、RHEL / CentOSシステムでPGXS拡張機能を構築しようとしていて、互換性のないスキップが表示された場合 ライブラリメッセージ、インストールしたPostgreSQL開発パッケージを確認することから始めます。
この特定の悪い組み合わせは、PostgreSQL9.0パッケージの将来のアップデートによってブロックされる可能性があります。 RPMでこのようなトラブルシューティングを行う良い例はあまりないので、とにかく共有するのは面白いと思いました。私はかつて、RHEL 5 /CentOS5へのPostgreSQL8.2RPMのインストールというタイトルの記事を書きましたが、ここではもう少し背景を説明します。しかし、64ビットプラットフォームが普及する前、そしてRPMを介して複数のPostgreSQLバージョンを同時にインストールできるようになる前は、それらはもっと単純な時代でした。関連するアーキテクチャとともにインストールされたパッケージを一覧表示するための適切なRPMの呪文を知ることは、RPMの地獄から抜け出すための今日の重要なトリックです。