Tidak ada NULLs, urutan byte yang tidak valid untuk pengkodean "UTF8": 0x00

12

Saya telah menghabiskan 8 jam terakhir mencoba untuk mengimpor output dari 'mysqldump --compatible = postgresql' ke PostgreSQL 8.4.9, dan saya sudah membaca setidaknya 20 utas berbeda di sini dan sudah di tempat lain tentang masalah khusus ini, tetapi tidak menemukan jawaban yang dapat digunakan nyata yang bekerja.

Data MySQL 5.1.52 dicampakkan:

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

Server PostgreSQL 8.4.9 sebagai tujuan

Memuat data dengan 'psql -U rt_user -f foo' sedang melaporkan (banyak dari ini, inilah salah satu contoh):

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".

Menurut yang berikut, tidak ada NULL (0x00) karakter dalam file input.

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

Demikian juga, pemeriksaan lain dengan Perl tidak menunjukkan NULL:

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

Seperti "PETUNJUK" dalam kesalahan yang disebutkan, saya telah mencoba segala cara yang mungkin untuk mengatur 'client_encoding' ke 'UTF8', dan saya berhasil tetapi tidak berpengaruh terhadap penyelesaian masalah saya.

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#

Sempurna, belum:

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".
...

Kecuali jawaban "Menurut Hoyle" yang benar, yang akan sangat fantastis untuk didengar, dan mengetahui bahwa saya benar-benar tidak peduli tentang mempertahankan karakter non-ASCII untuk data yang jarang direferensikan ini, saran apa yang Anda miliki?

Pembaruan: Saya mendapatkan kesalahan yang sama dengan versi ASCII-satunya dari file dump yang sama pada waktu impor. Benar-benar membingungkan:

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

Salah satu tabel yang dimaksud didefinisikan sebagai:

                                        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)

Saya tidak memiliki kebebasan untuk mengubah jenis untuk bagian skema DB mana pun. Melakukannya kemungkinan akan merusak pembaruan perangkat lunak di masa mendatang , dll.

Kolom masalah yang mungkin adalah 'konten' dari jenis 'teks' (mungkin yang lain di tabel lain juga). Seperti yang sudah saya ketahui dari penelitian sebelumnya, PostgreSQL tidak akan mengizinkan NULL dalam nilai 'teks'. Namun, silakan lihat di atas di mana sed dan Perl tidak menunjukkan karakter NULL, dan kemudian lebih jauh ke bawah di mana saya menghapus semua karakter non-ASCII dari seluruh file dump tetapi masih barfs.

jblaine
sumber
2
Seperti apa baris 29 dari file dump Anda? Sesuatu seperti head -29 foo | tail -1 | cat -vmungkin berguna.
mu terlalu pendek
Apa definisi dari tabel yang terpengaruh dan seperti apa garis yang menyinggung itu terlihat?
tscho
Ini ~ 1MB data perusahaan. Tapi saya mengerti tujuan Anda. Inilah akhir dari pemikiran itu (tolong maafkan bahasa Prancis saya di akhir inti / tempel): gist.github.com/1525788
jblaine
tscho: Seperti yang ditunjukkan, contoh baris kesalahan adalah salah satu dari ratusan kesalahan ini.
jblaine

Jawaban:

3

Satu atau lebih dari bidang karakter / teks MUNGKIN memiliki 0x00 untuk isinya.

Coba yang berikut ini:

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

Jika ini mengembalikan satu baris saja, maka coba perbarui bidang karakter / teks tersebut dengan:

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

Setelah itu, coba MYSQLDUMP lain ... (dan metode impor PostgreSQL).

Farley Inglis
sumber
Ini membantu saya menemukan karakter nol saya yang tersesat, meskipun saya perlu menggunakannya colname LIKE concat('%', 0x00, '%'). Menemukannya di bidang yang berisi array PHP serial.
cimmanon
5

Saya memiliki masalah yang sama menggunakan MySQL versi 5.0.51 dan Postgres versi 9.3.4.0. Saya memecahkan "urutan byte tidak valid untuk pengkodean" UTF8 ": 0x00" masalah setelah melihat komentar Daniel Vérité bahwa "mysqldump dalam mode postgresql akan membuang byte byte sebagai \ 0 dalam string, jadi Anda mungkin ingin mencari urutan karakter."

Cukup yakin grep akhirnya mengungkapkan karakter NULL.

grep \\\\0 dump.sql

Saya mengganti karakter NULL menggunakan perintah berikut

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

Postgres kemudian berhasil memuat dump.sql

Jadence
sumber
4

Anda bisa mendapatkan kesalahan ini tanpa byte NULL atau karakter non-ascii dalam file. Contoh dalam database utf8:

select E'ab\0cd';

akan menghasilkan:

GALAT: urutan byte tidak valid untuk pengkodean "UTF8": 0x00 PETUNJUK: Kesalahan ini juga dapat terjadi jika urutan byte tidak cocok dengan pengkodean yang diharapkan oleh server, yang dikendalikan oleh "client_encoding".

mysqldump dalam mode postgresql akan membuang byte nol sebagai \ 0 dalam string, jadi Anda mungkin ingin mencari urutan karakter tersebut.

Daniel Vérité
sumber
0

Saya setengah ingat masalah seperti ini. Saya pikir saya akhirnya memigrasi skema kemudian membuang data sebagai csv dan memuat data dari file csv. Saya ingat harus memperbarui file csv (menggunakan alat unix seperti sed atau unixtodos) atau menggunakan calc kantor terbuka (excell) untuk memperbaiki beberapa item yang merupakan kesalahan pada langkah impor - bisa semudah membuka dan menyimpan kembali mengajukan.

adam f
sumber