私は過去8時間を費やして 'mysqldump --compatible = postgresql'の出力をPostgreSQL 8.4.9にインポートしようとしました。この特定の問題については、すでにここと他の場所で少なくとも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スキーマの一部のタイプを変更する自由がありません。これを行うと、将来の software などのアップグレードが中断される可能性があります。
問題の可能性のある列は、タイプが「テキスト」の「コンテンツ」です(おそらく他のテーブルの他の列も同様です)。以前の調査ですでに知っているように、PostgreSQLは 'text'値にNULLを許可しません。ただし、sedとPerlの両方でNULL文字が表示されない上記を参照してください。次に、ダンプファイル全体からすべての非ASCII文字を削除しますが、それでもまだbarfsです。
それらの文字/テキストフィールドの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インポート方法)を試してください。
MySQLバージョン5.0.51とPostgresバージョン9.3.4.0を使用して同じ問題が発生しました。 DanielVéritéのコメント「Postgresqlモードのmysqldumpはnullバイトを文字列の\ 0としてダンプするので、おそらくその文字シーケンスを検索したい」というコメントを見て、「エンコーディング "UTF8"の無効なバイトシーケンス:0x00」の問題を解決しました。
案の定、grepは最終的にNULL文字を明らかにしました。
grep \\\\0 dump.sql
次のコマンドを使用してNULL文字を置き換えました
sed -i BAK 's/\\0//g' dump.sql
その後、Postgresはdump.sqlを正常にロードできました
このエラーは、ファイルにNULLバイトや非ASCII文字がない場合に発生します。 utf8データベースの例:
select E'ab\0cd';
生成されます:
エラー:「UTF8」をエンコードするための無効なバイトシーケンス:0x00ヒント:このエラーは、「client_encoding」によって制御されるサーバーが予期するエンコードとバイトシーケンスが一致しない場合にも発生する可能性があります。
postgresqlモードのmysqldumpは、nullバイトを文字列の\ 0としてダンプするため、おそらくその一連の文字を検索する必要があります。
私はこのような問題を半分覚えています。スキーマを移行し、データをcsvとしてダンプし、csvファイルからデータをロードしたと思います。 (sedやunixtodosなどのunixツールを使用して)csvファイルを更新するか、Open Office calc(excell)を使用してインポート手順でエラーになったいくつかのアイテムを修正する必要があったことを覚えています。ファイル。