birdpgpool と LargeObject(2)

pgpool と LargeObject(2)

以前、pgpool1(http://www2b.biglobe.ne.jp/~caco/pgpool/)を参照のこと。] 経由でもちょっとした工夫で LargeObject を使うことができる、という話を書きましたが、やっぱりなかなか難しいのだった、というお話。
というのも、LargeObject として格納されているデータによっては、PostgreSQL では必須の analyze2 を実行した場合に oid が消費される可能性があり、レコード数の多いテーブルでの analyze はランダム・サンプリングとなりますから、プライマリ・セカンダリ側で同じ行が選択される保証はなく、従って oid の同期が取れなくなってしまうのですね。analyze のタイミングを合わせたり LargeObject 更新との同期を取ったとしても、単一の analyze コマンドの実行内で oid がずれてしまうために対処のしようがないのでした。残念!
PostgreSQL では LargeObject を使わなくてもふつうのテーブルに 2Gbytes までのバイナリデータを格納することができますが、ただこの方法にはバックエンドプロセスのサイズがふくらむ、処理速度がのろい、といった欠点があります。それらの欠点を回避するためには、大きなバイナリファイルを数 Kbytes くらいの小さいチャンクに分割し、複数レコードとして格納する、という方法があって、LargeObject を使った場合ほどの性能は出ないけれども、とりあえず現実的なメモリ消費量、処理速度で大きなバイナリファイルを扱うことができます。今回も結局この方法で逃げることにしました。


  1. PostgreSQL 用のコネクションプーリング・レプリケーションサーバ。詳しくは[こちら ↩︎

  2. テーブルの統計情報を更新するコマンドで、コストベースオプティマイザしか持たない PostgreSQL ではまともな速度で query を実行するためには定期的な実行が必須なのです。 ↩︎