かぴぶろぐ

またかぴったかと思った・・・(´A`;)

Postgresql ERROR: invalid byte sequence for encoding

カテゴリ[ Postgres ]

Postgresql ERROR:  invalid byte sequence for encoding


旧サーバから新サーバへDBデータ移行時にこのエラーでハマりましたorz
盛大にハマりましたorz

旧サーバ:

Linux 2.4.21-27.0.2.ELsmp CentOS x86_64
psql (PostgreSQL) 8.2.5

新サーバ:

Linux 2.6.9-78.0.8.ELsmp x86_64 CentOS release 4.7 (Final)
psql (PostgreSQL) 8.3.7

まず、gzipで固めたdmpデータを作る。

> pg_dumpall -U [username] | gzip -9c > old_db.gz


で新サーバにFTPで転送し、新サーバに入れ込む。

> gzip -dc old_db.gz | psql -U [username] -f -


この作業はしょっちゅうやってて、いつもなら問題なく終わる。
しかし、今回は途中で

psql:<stdin>:4043843: ERROR:  invalid byte sequence for encoding "UTF8": 0xfc
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".
CONTEXT:  COPY [table name], line 268708


と出て止まってしまった( ̄〇 ̄;)
client_encodingで、色々調べながら何度か挑戦したが、鉄壁。
この行を通過させてくれない・・。

やった事。

http://www.deftrash.com/blog/archives/2007/09/invalid_byte_sequence_for_enco.html
の人の情報をもとに

export PGCLIENTENCODING=SQL_ASCII(旧サーバで)

ダメ。

新旧サーバで

export PGCLIENTENCODING=SQL_ASCII

はいダメ。

export LANG=Cをプラス(新旧サーバで)

これもダメ。

psqlでログイン後、

> show client_encoding;

で両方ともUTF8になってる事を確認。
合ってるよなぁ・・・(>_<;)

PGCLIENTENCODING=SQL_ASCIIはconfでやるべき?
とPGDATA下のpostgresql.confで

#client_encoding = sql_ascii

のコメントを外し、
postgresを再起動してダンプ>リストア

これもダメ。

んん~。これはダンプファイルを直接editするしかないか(>_<;;;)
しかし、エラー箇所からも分かるとおり、ファイルサイズ5Gくらいあって開くだけで泣ける。
ていうか開かない・・。
ていうか文字化けしてて修正してもcopyコマンドぶち壊すかも。
ていうか・・・当然ここだけとは限らない。。。。(1000件とかあったらどうする?)

どうしたものかと色々調べてて、神の光が!

http://www.gobu.jp/psql_21.php

こちらの人のやり方。

結果、やった事。

postgres.conf

encoding周り。

#client_encoding = sql_ascii

# These settings are initialized by initdb, but they can be changed.
lc_messages = 'en_US.UTF-8'                     # locale for system error message
                                        # strings
lc_monetary = 'en_US.UTF-8'                     # locale for monetary formatting
lc_numeric = 'en_US.UTF-8'                      # locale for number formatting
lc_time = 'en_US.UTF-8'                         # locale for time formatting


両方同じ設定にした。

もう色々ぐちゃぐちゃだったので、新サーバはinitdbから。

> initdb -D /opt/database/pgsql --encoding=utf-8 --no-locale
> createdb -U postgres --encoding=utf8 [db_name]

で、重要なのはここから。
旧サーバで

> pg_dump -U [user] -F p -D -v -i -f old_db.sql [db_name]

オプション多いなぁ・・・。
で新サーバで

> psql -U [user] -d [db_name] -f old_db.sql

すると画面いっぱいにINSERTが広がる。

待つ事・・・数時間。

 

 

ヤッターーーーーーーーーーーーー!(T〇T;)/


神記事に救われました。

結果的に新旧DBの各テーブルrecord数をカウントしていったら、エラーが出ていたテーブルのrecord 1件のみ、insertされていなかった。

この1件に・・・orz

参考URL

http://kapi.jp/kapi_blog/236

2009年06月02日

関連カテゴリ Postgres

この記事のコメント

この記事にコメントする