"UTF8"인코딩을위한 NULL은 아니지만 유효하지 않은 바이트 시퀀스 : 0x00


12

지난 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'로 데이터를로드하는 것이보고됩니다 (많은 것들이 여기에 하나의 예가 있습니다).

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

해당 테이블 중 하나는 다음과 같이 정의됩니다.

                                        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 스키마의 일부에 대한 유형을 변경할 자유가 없습니다. 그렇게하면 향후 소프트웨어 업그레이드 등 이 중단 될 수 있습니다 .

문제가 될 수있는 열은 'text'유형의 'content'(아마도 다른 테이블의 다른 것)입니다. 이전 연구에서 이미 알고 있듯이 PostgreSQL은 'text'값에 NULL을 허용하지 않습니다. 그러나 sed와 Perl이 NULL 문자를 표시하지 않는 위의 내용을 참조한 다음 전체 덤프 파일에서 ASCII가 아닌 모든 문자를 제거하지만 여전히 barfs 인 경우 아래를 참조하십시오.


2
덤프 파일의 29 행은 무엇입니까? 같은 head -29 foo | tail -1 | cat -v것이 사용되었을 수 있습니다.
mu는

영향을받는 테이블의 정의는 무엇이며 문제의 행은 어떻게 생깁니 까?
tscho

~ 1MB의 회사 데이터입니다. 물론 당신은 어디로 향하고 있는지 이해합니다. 여기에 생각의 그 라인의 끝 (/ 요지의 말에 내 프랑스어 용서 붙여주세요)이다 : gist.github.com/1525788
jblaine

tscho : 표시된대로 오류 라인 예제는 이러한 오류 중 수백 중 하나입니다.
jblaine

답변:


3

그러한 문자 / 텍스트 필드 중 하나 이상은 그 내용에 대해 0x00을 가질 수 있습니다.

다음을 시도하십시오 :

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

이것이 단일 행을 반환하면 해당 문자 / 텍스트 필드를 다음과 같이 업데이트하십시오.

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

그런 다음 다른 MYSQLDUMP ... (및 PostgreSQL import method)를 시도하십시오.


이렇게하면을 사용해야하는 길 잃은 null 문자를 찾는 데 도움이되었습니다 colname LIKE concat('%', 0x00, '%'). 직렬화 된 PHP 배열을 포함하는 필드에서 발견했습니다.
cimmanon

5

MySQL 버전 5.0.51과 Postgres 버전 9.3.4.0을 사용하는 것과 동일한 문제가있었습니다. "postgresql 모드의 mysqldump가 문자열에서 null 바이트를 \ 0으로 덤프하므로 해당 문자 시퀀스를 검색하고 싶다"는 Daniel Vé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 힌트 :이 오류는 바이트 시퀀스가 ​​"client_encoding"에 의해 제어되는 서버에서 예상 한 인코딩과 일치하지 않는 경우에도 발생할 수 있습니다.

postgresql 모드의 mysqldump는 문자열에서 null 바이트를 \ 0으로 덤프하므로 해당 문자 시퀀스를 검색하려고합니다.


0

반은 이런 문제를 기억합니다. 스키마를 마이그레이션 한 다음 데이터를 csv로 덤프하고 csv 파일에서 데이터를로드하는 것으로 끝났습니다. csv 파일을 업데이트 (sed 또는 unixtodos와 같은 유닉스 도구 사용) 또는 open office calc (excell)를 사용하여 가져 오기 단계에서 오류가 발생한 일부 항목을 수정해야한다는 것을 기억합니다. 파일.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.