NULLはありませんが、「UTF8」をエンコードするための無効なバイトシーケンス:0x00


12

'mysqldump --compatible = postgresql'の出力をPostgreSQL 8.4.9にインポートしようとして過去8時間を費やし、この特定の問題について少なくとも20の異なるスレッドをここおよび他の場所で既に読んでいますが、実際に使用可能な答え。

MySQL 5.1.52データのダンプ:

mysqldump -u root -p --compatible=postgresql --no-create-info --no-create-db --default-character-set=utf8 --skip-lock-tables rt3 > foo

宛先としてのPostgreSQL 8.4.9サーバー

「psql -U rt_user -f foo」を使用してデータをロードすると、レポートが作成されます(これらの多くは、1つの例です)。

psql:foo:29: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
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".

以下によると、入力ファイルにはNULL(0x00)文字はありません。

database-dumps:rcf-temp1# sed 's/\x0/ /g' < foo > nonulls
database-dumps:rcf-temp1# sum foo nonulls
04730 2545610 foo
04730 2545610 nonulls
database-dumps:rcf-temp1# rm nonulls

同様に、Perlを使用した別のチェックではNULLが示されていません。

database-dumps:rcf-temp1# perl -ne '/\000/ and print;' foo
database-dumps:rcf-temp1#

エラーの「ヒント」に記載されているように、「client_encoding」を「UTF8」に設定するあらゆる方法を試しましたが、成功しましたが、問題の解決には効果がありません。

database-dumps:rcf-temp1# psql -U rt_user --variable=client_encoding=utf-8 -c "SHOW client_encoding;" rt3
 client_encoding
-----------------
 UTF8
(1 row)

database-dumps:rcf-temp1#

完璧な、まだ:

database-dumps:rcf-temp1# psql -U rt_user -f foo --variable=client_encoding=utf-8 rt3
...
psql:foo:29: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
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".
...

「Hoyleによる」という正解を除いて、これは聞くのは素晴らしいことですが、このめったに参照されないデータに対してASCII以外の文字を保持することは本当に気にしないということを知っています。

更新:インポート時に同じダンプファイルのASCIIのみのバージョンで同じエラーが発生します。本当に気が遠くなる:

database-dumps:rcf-temp1# # convert any non-ASCII character to a space
database-dumps:rcf-temp1# perl -i.bk -pe 's/[^[:ascii:]]/ /g;' mysql5-dump.sql
database-dumps:rcf-temp1# sum mysql5-dump.sql mysql5-dump.sql.bk
41053 2545611 mysql5-dump.sql
50145 2545611 mysql5-dump.sql.bk
database-dumps:rcf-temp1# cmp mysql5-dump.sql mysql5-dump.sql.bk
mysql5-dump.sql mysql5-dump.sql.bk differ: byte 1304850, line 30
database-dumps:rcf-temp1# # GOOD!
database-dumps:rcf-temp1# psql -U postgres -f mysql5-dump.sql --variable=client_encoding=utf-8 rt3
...
INSERT 0 416
psql:mysql5-dump.sql:30: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
HINT:  This error can also happen if the byte sequence does not match the encod.
INSERT 0 455
INSERT 0 424
INSERT 0 483
INSERT 0 447
INSERT 0 503
psql:mysql5-dump.sql:36: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
HINT:  This error can also happen if the byte sequence does not match the encod.
INSERT 0 502
INSERT 0 507
INSERT 0 318
INSERT 0 284
psql:mysql5-dump.sql:41: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
HINT:  This error can also happen if the byte sequence does not match the encod.
INSERT 0 382
INSERT 0 419
INSERT 0 247
psql:mysql5-dump.sql:45: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
HINT:  This error can also happen if the byte sequence does not match the encod.
INSERT 0 267
INSERT 0 348
^C

問題のテーブルの1つは次のように定義されます。

                                        Table "public.attachments"
     Column      |            Type             |                        Modifie
-----------------+-----------------------------+--------------------------------
 id              | integer                     | not null default nextval('atta)
 transactionid   | integer                     | not null
 parent          | integer                     | not null default 0
 messageid       | character varying(160)      |
 subject         | character varying(255)      |
 filename        | character varying(255)      |
 contenttype     | character varying(80)       |
 contentencoding | character varying(80)       |
 content         | text                        |
 headers         | text                        |
 creator         | integer                     | not null default 0
 created         | timestamp without time zone |
Indexes:
    "attachments_pkey" PRIMARY KEY, btree (id)
    "attachments1" btree (parent)
    "attachments2" btree (transactionid)
    "attachments3" btree (parent, transactionid)

DBスキーマの任意の部分のタイプを変更する自由がありません。そうすると、ソフトウェアの将来のアップグレードなどが中断される可能性があります

問題の可能性の高い列は、タイプが「テキスト」の「コンテンツ」です(他のテーブルの他のフィールドも同様です)。以前の調査ですでに知っているように、PostgreSQLは「テキスト」値にNULLを許可しません。ただし、上記のsedとPerlの両方にNULL文字が表示されていない場所を参照してください。さらに、ダンプファイル全体からすべての非ASCII文字を取り除きますが、それでもbarfsです。


2
ダンプファイルの29行目はどのように見えますか?何かが役に立つhead -29 foo | tail -1 | cat -vかもしれません。
muが短すぎる

影響を受けるテーブルの定義は何ですか?また、問題の行はどのように見えますか?
tscho

約1MBの会社データです。もちろん、あなたがどこに向かっているのか理解しています。ここにその考え方の終わりがあります(要旨/貼り付けの終わりに私のフランス語をご容赦ください):gist.github.com/1525788
jblaine

tscho:前述のように、エラー行の例はこれらの数百のエラーの1つです。
jblaine

回答:


3

これらの文字/テキストフィールドの1つ以上のコンテンツに0x00が含まれている場合があります。

以下を試してください:

SELECT * FROM rt3 where some_text_field = 0x00 LIMIT 1;

これが単一の行を返す場合は、次の文字/テキストフィールドを更新してみてください。

UPDATE rt3 SET some_text_field = '' WHERE some_text_field = 0x00;

その後、別のMYSQLDUMP ...(およびPostgreSQLのインポート方法)を試してください。


これは、を使用する必要がありましたが、迷っているヌル文字を見つけるのに役立ちましたcolname LIKE concat('%', 0x00, '%')。シリアル化されたPHP配列を含むフィールドでそれらを見つけました。
cimmanon 14年

5

MySQLバージョン5.0.51とPostgresバージョン9.3.4.0を使用しても同じ問題が発生しました。「postgresqlモードのmysqldumpは文字列でnullバイトを\ 0としてダンプするので、おそらくその文字列を検索したい」というDanielVéritéのコメントを見て、「エンコーディング「UTF8」の無効なバイトシーケンス:0x00」問題を解決しました。

案の定、grepはついにNULL文字を明らかにしました。

grep \\\\0 dump.sql

次のコマンドを使用してNULL文字を置き換えました

sed -i BAK 's/\\0//g' dump.sql

その後、Postgresはdump.sqlを正常にロードできました。


4

このエラーは、ファイルにNULLバイトや非ASCII文字が含まれていなくても取得できます。utf8データベースの例:

select E'ab\0cd';

生成されます:

エラー:「UTF8」をエンコードするための無効なバイトシーケンス:0x00

postgresqlモードのmysqldumpは、文字列でnullバイトを\ 0としてダンプするため、おそらくその文字シーケンスを検索する必要があります。


0

私はこのような問題を半分覚えています。スキーマを移行し、データをcsvとしてダンプし、csvファイルからデータをロードしたと思います。私はcsvファイルを更新する必要があることを覚えています(sedやunixtodosなどのunixツールを使用する)、またはオープンオフィスcalc(excell)を使用してインポートステップでエラーだったいくつかのアイテムを修正します-ファイル。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.