지난 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 인 경우 아래를 참조하십시오.
head -29 foo | tail -1 | cat -v
것이 사용되었을 수 있습니다.