2002 年 12 月 20 日 (金) 自宅

とある事情で、 ある Web ベースのシステムのバックエンド DB と フロントエンドのサーバを、 1 日で別のマシンに置き換える準備をすることに。 朝にマシンのインストールを開始。 このついでに、PostgreSQL は 7.0 から 7.2.3 にアップグレードすることにしました。 この作業が…はまった。

まず、ラージオブジェクトを含む PostgreSQL 7.0 データのバックアップ。 やはり pg_dump で取ったデータから、 pg_restore で戻す方が確実だと思うのだけれども、 7.0 時代の pg_dump はラージオブジェクトをダンプする機能がない。 Web を漁ると、pg_dump は過去のバージョンの PostgreSQL サーバからもダンプができるらしく、 ラージオブジェクトを 7.0 のサーバから吸い出すこともできるらしい。

ということで、1 日でやるというリミットから考えて、 試行錯誤の末、安直な手順を考えました。

  1. まず、7.0 のマシン上で 7.2.3 をソースから make する。
  2. cp postgresql-7.2.3/src/bin/pg_dump/pg_dump /usr/local/bin/pg_dump72
  3. pg_dumpall -d > dumpfile でいったんデータをスキーマごとダンプ
  4. /usr/local/bin/pg_dump72 -Ft -b -a -d データベース名 > dump.tar
  5. 7.2 マシン上で psql -f dumpfile template1 でリストアする
  6. その後、7.2 マシン上で psql データベース名して、すべての table のデータを delete する (テーブルは drop しない)
  7. pg_restore -d データベース名 dump.tar

バックアップとして生成される tar ファイルの中には、 BLOB データのファイルが大量にあり、 ちゃんとラージオブジェクトもバックアップできているようです。 一応、strings(1) で見ると、ラージオブジェクト内のデータが確認できました。

で、さらにここで pg_restore まで順調に動き出したので、 やったぜ、これで OK! と思ったのですが…。 悲しいことに次のエラーが出て中断。

ERROR: Invalid EUC_JP character sequence found (0x....)

Google で調べると、どうも PostgreSQL 7.2 からは、 EUC などの文字コードのチェックが厳しくなっていて、 text のフィールドに EUC として不正なデータが入っていると、 そもそも INSERT できないらしい。 うひゃーっ! だから外字はお断り、って言ったのに… (^^;。

とはいってもすでに時は過ぎ行くのみ。 そういう根本的対策は年が明けたらやることに。 なんとか FreeBSD の distfiles に PostgreSQL 7.1.3 のソースを発見したので、 サーバ側とアプリケーション側の双方の PostgreSQL を 7.1.3 にバージョンダウンすることを決定。

CVSup から昔の ports を持ってくるのも面倒なうえ、 OS も PostgreSQL 7.2.3 より新しい FreeBSD 4.7-RELEASE なので、 そもそも昔の ports の Makefile が動くかどうかも分かりません。 ということで、仕方なく ports を使わずにソースから入れました。

で、上記手順の 7.2.3 を 7.1.3 に変えて一連の処理を実行し、成功! ラージオブジェクトもきちんと書き戻されたようです。

しかし、さらにここで問題が発生。 ラージオブジェクトを使うアプリケーションの一部が動作しない。 どうも lo_creat() が失敗しているらしい。 試行錯誤の結果、 7.0 では lo_creat の引数が、

my $lo = $conn->lo_creat(PGRES_INV_ARCHIVE);

だけでラージオブジェクトを生成できて読み書きできるのですが、 7.1 以降の lo_creat は、

my $lo = $conn->lo_creat(PGRES_INV_ARCHIVE|PGRES_INV_READ|PGRES_INV_WRITE);

にしないとそもそも lo_creat が PGRES_InvalidOid を返してきて、 ラージオブジェクトを生成できない…というのが原因でした。

うーん、久々に全速力ではまったな…。


このサイトへのリンクには何ら許可は必要ありません。 ただし、無断で写真をダウンロードして他の場所に掲載したり、 画像加工の素材として利用するなど、再配布に当たる行為はしないようにしてください。 また、このサイトへのリンクであることを明示すること無しに <img src="..."> などで他のページの内部に画像ファイルを取り込むことも、 ご遠慮下さい。