jbl*_*ine 13 mysql postgresql mysqldump
我花了过去 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
Run Code Online (Sandbox Code Playgroud)
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".
Run Code Online (Sandbox Code Playgroud)
根据以下内容,输入文件中没有 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
Run Code Online (Sandbox Code Playgroud)
同样,对 Perl 的另一项检查显示没有 NULL:
database-dumps:rcf-temp1# perl -ne '/\000/ and print;' foo
database-dumps:rcf-temp1#
Run Code Online (Sandbox Code Playgroud)
正如错误中的“提示”所提到的,我已经尝试了所有可能的方法将“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#
Run Code Online (Sandbox Code Playgroud)
完美,然而:
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".
...
Run Code Online (Sandbox Code Playgroud)
除非听到“根据霍伊尔的说法”正确答案,这会很棒,并且知道我真的不关心为这个很少引用的数据保留任何非 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
Run Code Online (Sandbox Code Playgroud)
有问题的表之一定义为:
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)
Run Code Online (Sandbox Code Playgroud)
我无权更改 DB 模式任何部分的类型。这样做可能会破坏软件的未来升级等。
可能的问题列是“文本”类型的“内容”(也许其他表格中的其他表格也是如此)。正如我从之前的研究中已经知道的那样,PostgreSQL 不允许在“文本”值中使用 NULL。但是,请参阅上面 sed 和 Perl 都没有显示 NULL 字符的地方,然后再往下看,我从整个转储文件中删除了所有非 ASCII 字符,但它仍然是 barfs。
小智 6
我在使用 MySQL 5.0.51 版和 Postgres 9.3.4.0 版时遇到了同样的问题。在看到 Daniel Vérité 的评论“postgresql 模式下的 mysqldump 会将空字节转储为字符串中的 \0,因此您可能想要搜索该字符序列”后,我解决了“用于编码“UTF8”的无效字节序列:0x00”问题。
果然,grep 终于显示了 NULL 字符。
grep \\\\0 dump.sql
Run Code Online (Sandbox Code Playgroud)
我使用以下命令替换了 NULL 字符
sed -i BAK 's/\\0//g' dump.sql
Run Code Online (Sandbox Code Playgroud)
然后 Postgres 能够成功加载 dump.sql
小智 4
这些字符/文本字段中的一个或多个其内容可能为 0x00。
请尝试以下操作:
SELECT * FROM rt3 where some_text_field = 0x00 LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
如果这返回任何单行,则尝试使用以下命令更新这些字符/文本字段:
UPDATE rt3 SET some_text_field = '' WHERE some_text_field = 0x00;
Run Code Online (Sandbox Code Playgroud)
然后,尝试另一种 MYSQLDUMP ...(和 PostgreSQL 导入方法)。
| 归档时间: |
|
| 查看次数: |
19430 次 |
| 最近记录: |