ソースデータベースがUTF8でエンコードされている場合、復元でUTF8無効なバイトシーケンスコピーエラーを解くにはどうすればよいですか?
-
16-10-2019 - |
質問
PostgreSQL 8.2.xデータベースを別のサーバーに移行するタスクが与えられました。これを行うには、PGADMIN 1.12.2(ちなみにUbuntu 11.04で)を使用し、カスタム/Compress形式(.backup)およびUTF8エンコーディングを使用してバックアップと復元を使用しています。
元のデータベースはUTF8にあります。
-- Database: favela
-- DROP DATABASE favela;
CREATE DATABASE favela
WITH OWNER = favela
ENCODING = 'UTF8'
TABLESPACE = favela
CONNECTION LIMIT = -1;
このデータベースは、宛先サーバーでまさにこのデータベースを作成しています。しかし、復元オプションを使用して.backupファイルからデータベースを復元すると、これらのエラーの一部が得られます。
pg_restore: restoring data for table "arena"
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 2173; 0 35500 TABLE DATA arena favela
pg_restore: [archiver (db)] COPY failed: ERROR: invalid byte sequence for encoding "UTF8": 0xe3a709
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 arena, line 62
実際にこのエラーをトリガーしたレコードを確認すると、一部のVartextフィールドにはç(「Caça」などのポルトガル語で使用されています)のような異なる文字があり、レコード内のテキストから手動で削除すると、次のレコードにエラーが渡されます。コピーにエラーがある場合は、このテーブルにデータの挿入を停止するためです。そして、私はこれを達成するためにそれらを1つずつ手動で置き換えたくありません。
しかし、UTF8を使用すると、この種の問題はないはずですよね?
そもそも彼らがどうやってそこにたどり着いたのかわかりません。私はデータベースを移行しているだけであり、どういうわけかデータベースはLATIN1のようなものであり、その後UTF8に不適切に変更されたことを驚かせます。
テーブル/データベースにUTF8シーケンスが無効かどうかを確認する方法はありますか?または、これらの文字をuft8に施行/再構成する方法は、復元を実行しても問題に直面しませんか?
前もって感謝します。
解決
インターネットを掘り下げて、これがかなり一般的な問題であることがわかりました。一般的な解決策は、プレーンテキスト形式のダンプを使用し、ICONVを使用してエンコードを修正することです。
ここ それについての詳細情報です。
他のヒント
「そもそも彼らがどうやってそこに着いたのかわかりません」
説明されているように起こった可能性があります ここ - これにより8.4でエラーが生成されます。
任意のテキストタイプ(IEテキスト、Varchar(10)など)のテーブルを作成すると、Octal Escapesを使用してそのフィールドに無効なバイトシーケンスを挿入できます。
たとえば、UTF8エンコードされたデータベースがある場合は、次のことができます。
=>テーブルfoo(tテキスト)を作成します。
=> foo値に挿入(e ' 377');
これで、テーブルをコピーすると、結果のファイルをコピーすることはできません。つまり、PG_DUMPバックアップが復元できなくなります。データを元に戻す唯一の方法は、その価値を再展開することです。
これには良い投稿があります 素晴らしいブログ 一般的な問題とそれらに対処するいくつかの方法について
UNIX/Linux環境で使用されるデフォルトのエンコードである可能性があります。現在デフォルトのエンコーディングであるかを確認するには、以下を実行します。
$ echo $LANG
en_US
この場合、コピーコマンドが依存しているUTF-8エンコードではないことが明確にわかります。
これを修正するために、ラング変数を次の例に設定するだけです。
$ export LANG=en_US.UTF-8
注:これは、現在のセッションでのみ利用できます。 〜/.bashrcまたは同様に追加して、将来のシェルセッションの起動時に使用できるようにします。
有効な文字(例:漢字)を他の文字に変換する可能性があるため、プレーンテキストダンプで盲目的に実行することはお勧めしません。コマンド以下で実行して、無効なUTF8文字を見つける方が良いです。
grep -naxv '.*' plain_text_dump.sql
次に、特定のデータでICONVを実行します。小切手 詳細な段階的な説明のためのこのドキュメント.