PostgreSQL7.4系のEUCのDBを8.1系のEUCのDBへ移行する(明日のための私的メモ)

てことで、今日はサーバの移行作業をやっててPostgreSQLのDBをダンプ&リストアするときに問題になったので、id:chaorukoに教えてもらった方法を明日試す。というメモ。
フツーに(?)pg_dumpダンプして、リストアしようとしたらこんなエラーがでてた。

invalid byte sequence for encoding "EUC_JP"
HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding"

もともと300MBくらいのデータが50MBくらいになってたからおかしいなーと思ったんだ(ーー;
で、pd_dumpするときは、INSERT文で出力するようにしたら問題は少なくなるらしい。さらに、それを以下のPerlスクリプトでダメな文字を置き換えるとよいといこと。
(↓のメーリングリストから引用でつ)
http://ml.postgresql.jp/pipermail/pgsql-jp/2003-October/014808.html

#!/usr/bin/perl
# ------------------------------------------------------------------------
#   remove-invalid-euc.pl
#   Copyright 2003 Kawasaki Yusuke, Kappe Inc.
# ------------------------------------------------------------------------
#   "Invalid EUC_JP character sequence found" を回避するため、
#   標準入力からEUCコードのテキストを読み取って、
#   不正な文字コードがあれば『〓』に変換して標準出力に書き出します
#   変換行および COPY で始まる行は、確認用に標準エラー出力にも書き出します
# ------------------------------------------------------------------------
#   Usage: perl remove-invalid-euc.pl < input.txt > output.txt
# ------------------------------------------------------------------------
    use strict;
    my $GETA = "\xa2\xae";
# ------------------------------------------------------------------------
    while (<>) {
        my $changed = 0;
        print STDERR $_ if /^COPY /i;
        $changed ++ if ( s/[\x7f-\x8d\x8f-\x9f]/$GETA/sg );
        $changed ++ while ( s/(^|[\000-\177])((?:[\200-\377]{2})*)([\200-\377])([\000-\177]|$)/$1$2$GETA$4/s );
        print STDERR $_ if $changed;
        print $_;
    }
# ------------------------------------------------------------------------

すごいね。このスクリプト
さらに、pg_dumpではスキーマと、データを別々に出力することができるので、そうした方がいいとのこと。なんか、よく分からんけど、昔、試行錯誤した結果そうした方がいいってことになったそうなので素直に従うこととする。
そして、最終的には下のような作業になる予定。(明日ためす)

# まず、-sオプションでスキーマだけを出力
pg_dump -f sampledb_schema.sql -s sampledb
# 次に、-a -dオプションでデータだけをINSERT文で出力
pg_dump -f sampledb_insert.sql -a -d sampledb
# 先ほどのPerlスクリプトをかましてダメな文字を変換
perl remove-invalid-euc.pl < sampledb_insert.sql > sampledb_insert_valid.sql

そして、このあと新しいPostgreSQLにダンプを持っていきリストア完了!ってことになるはず。
準備おっけー。