Không có NULL, nhưng chuỗi byte không hợp lệ để mã hóa UTF8 '': 0x00


12

Tôi đã dành 8 giờ qua để cố gắng nhập đầu ra của 'mysqldump --compiverse = postgresql' vào PostgreQuery 8.4.9 và tôi đã đọc ít nhất 20 luồng khác nhau ở đây và chưa biết về vấn đề cụ thể này, nhưng không tìm thấy câu trả lời thực sự có thể sử dụng mà làm việc.

Dữ liệu MySQL 5.1.52 bị hủy:

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

Máy chủ PostgreSQL 8.4.9 làm đích

Đang tải dữ liệu với 'psql -U rt_user -f foo' đang báo cáo (nhiều trong số này, đây là một ví dụ):

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

Theo sau, không có ký tự NULL (0x00) trong tệp đầu vào.

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

Tương tự, một kiểm tra khác với Perl cho thấy không có NULL:

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

Như "GỢI Ý" trong lỗi đề cập, tôi đã thử mọi cách có thể để đặt 'client_encoding' thành 'UTF8', và tôi thành công nhưng nó không có tác dụng gì trong việc giải quyết vấn đề của tôi.

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#

Hoàn hảo, chưa:

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

Chặn câu trả lời đúng "Theo Hoyle", sẽ rất tuyệt khi nghe và biết rằng tôi thực sự không quan tâm đến việc giữ bất kỳ ký tự không phải ASCII nào cho dữ liệu ít khi được tham chiếu này, bạn có đề xuất gì?

Cập nhật: Tôi gặp lỗi tương tự với phiên bản chỉ ASCII của cùng một tệp kết xuất tại thời điểm nhập. Thực sự tâm trí boggling:

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

Một trong các bảng trong câu hỏi được định nghĩa là:

                                        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)

Tôi không có quyền tự do thay đổi loại cho bất kỳ phần nào của lược đồ DB. Làm như vậy có thể sẽ phá vỡ các bản nâng cấp trong tương lai của phần mềm , v.v.

Cột vấn đề có thể là 'nội dung' của loại 'văn bản' (có lẽ các loại khác trong các bảng khác). Như tôi đã biết từ nghiên cứu trước đây, PostgreSQL sẽ không cho phép NULL trong các giá trị 'văn bản'. Tuy nhiên, vui lòng xem ở trên nơi cả sed và Perl không hiển thị các ký tự NULL, và sau đó tiếp tục xuống nơi tôi loại bỏ tất cả các ký tự không phải ASCII khỏi toàn bộ tệp kết xuất nhưng nó vẫn còn barfs.


2
Dòng 29 của tệp kết xuất của bạn trông như thế nào? Một cái gì đó giống như head -29 foo | tail -1 | cat -vcó thể được sử dụng.
mu quá ngắn

Định nghĩa của bảng bị ảnh hưởng là gì và dòng vi phạm trông như thế nào?
tscho

Đó là ~ 1 MB dữ liệu công ty. Tôi hiểu nơi bạn đang đứng tất nhiên, mặc dù. Đây là kết thúc của dòng suy nghĩ đó (xin vui lòng tha thứ tiếng Pháp của tôi ở cuối ý chính / dán): gist.github.com/1525788
jblaine

tscho: Như đã chỉ ra, dòng lỗi ví dụ đó là một trong hàng trăm lỗi này.
jblaine

Câu trả lời:


3

Một hoặc nhiều trường ký tự / văn bản CÓ THỂ có 0x00 cho nội dung của nó.

Hãy thử như sau:

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

Nếu điều này trả về bất kỳ hàng nào thì hãy thử cập nhật các trường ký tự / văn bản đó bằng:

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

Sau đó, hãy thử một MYSQLDUMP khác ... (và phương thức nhập PostgreSQL).


Điều này giúp tôi tìm thấy các ký tự null đi lạc của mình, mặc dù tôi cần sử dụng colname LIKE concat('%', 0x00, '%'). Tìm thấy chúng trong các trường có chứa các mảng PHP được tuần tự hóa.
cimmanon

5

Tôi gặp vấn đề tương tự khi sử dụng phiên bản MySQL 5.0.51 và Postgres phiên bản 9.3.4.0. Tôi đã giải quyết vấn đề "chuỗi byte không hợp lệ để mã hóa vấn đề" UTF8 ": 0x00" sau khi thấy nhận xét của Daniel Vérité rằng "mysqldump trong chế độ postgresql sẽ kết xuất các byte rỗng dưới dạng \ 0 trong chuỗi, vì vậy bạn có thể muốn tìm kiếm chuỗi ký tự đó."

Chắc chắn một grep cuối cùng đã tiết lộ các ký tự NULL.

grep \\\\0 dump.sql

Tôi đã thay thế các ký tự NULL bằng lệnh sau

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

Postgres sau đó đã có thể tải dump.sql thành công


4

Bạn có thể gặp lỗi này mà không có bất kỳ byte NULL hoặc bất kỳ ký tự không phải mã ascii nào trong tệp. Ví dụ trong cơ sở dữ liệu utf8:

select E'ab\0cd';

sẽ mang lại:

LRI: chuỗi byte không hợp lệ để mã hóa "UTF8": 0x00 GỢI Ý: Lỗi này cũng có thể xảy ra nếu chuỗi byte không khớp với mã hóa mà máy chủ mong đợi, được điều khiển bởi "client_encoding".

mysqldump trong chế độ postgresql sẽ kết xuất các byte rỗng dưới dạng \ 0 trong chuỗi, vì vậy bạn có thể muốn tìm kiếm chuỗi ký tự đó.


0

Tôi nhớ một nửa vấn đề như thế này. Tôi nghĩ rằng tôi đã kết thúc việc di chuyển lược đồ sau đó kết xuất dữ liệu dưới dạng csv và tải dữ liệu từ tệp csv. Tôi nhớ phải cập nhật tệp csv (sử dụng các công cụ unix như sed hoặc unixtodos) hoặc sử dụng văn phòng mở calc (excell) để sửa một số mục bị lỗi trong bước nhập - có thể đơn giản như mở và lưu lại tập tin.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.