当源数据库以UTF8编码时,如何解决还原时UTF8无效字节序列复制错误?


17

我获得了将PostgreSQL 8.2.x数据库迁移到另一台服务器的任务。为此,我使用的是pgAdmin 1.12.2(顺便说一句在Ubuntu 11.04上),并使用通过自定义/压缩格式(.backup)和UTF8编码进行的备份和还原。

原始数据库位于UTF8中,如下所示:

-- Database: favela

-- DROP DATABASE favela;

CREATE DATABASE favela
  WITH OWNER = favela
       ENCODING = 'UTF8'
       TABLESPACE = favela
       CONNECTION LIMIT = -1;

我正在目标服务器上完全像这样创建此数据库。但是,当我使用Restore选项从.backup文件还原数据库时,它给了我一些错误:

pg_restore: restoring data for table "arena"
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 2173; 0 35500 TABLE DATA arena favela
pg_restore: [archiver (db)] COPY failed: ERROR:  invalid byte sequence for encoding "UTF8": 0xe3a709
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".
CONTEXT:  COPY arena, line 62

当我检查哪个记录触发了此错误时,实际上某些vartext字段具有变音符,例如ç(在葡萄牙语中使用,例如“caça”),当我手动将其从记录中的文本中删除时,错误会传递到下一个记录拥有它们-因为复制时出错,它将停止在此表上插入数据。而且我不想手动替换它们来完成此操作。

但这有点奇怪,因为使用UTF8不应出现此类问题,对吗?

我不知道他们是如何到达那里的。我只是在迁移数据库,并且我认为数据库在某种程度上就像在LATIN1中一样,然后被不正确地更改为UTF8。

有什么方法可以检查表/数据库是否具有无效的UTF8序列?还是以任何方式将这些字符强制执行/转换为UFT8,以便在执行还原时不会遇到任何问题?

提前致谢。

Answers:


8

在互联网上挖掘,我已经看到这是一个非常普遍的问题。常见的解决方案是使用纯文本格式转储,并将其通过iconv进行输入以更正编码。

是有关的更多信息。


使用iconv转换为丢弃无效符号的UTF-32,然后返回UTF-8,从UTF-8到UTF-8的转换将无法捕获所有错误代码点。(例如孤儿代孕)
Jasen 2015年

7

“我不知道他们是怎么到达那里的”

描述它可能发生在这里 -尽管这在8.4生成错误:

如果创建具有任何文本类型(例如,文本,varchar(10)等)的表,则可以使用八进制转义符将无效的字节序列插入该字段。

例如,如果您具有UTF8编码的数据库,则可以执行以下操作:

=>创建表foo(t TEXT);

=>插入foo VALUES(E'\ 377');

现在,如果您将表复制出来,则无法将结果文件复制回来。这意味着您的pg_dump备份将无法还原。恢复数据的唯一方法是重新转义该值。

这个优秀的博客上有一篇很好的文章,介绍了一般性问题以及解决这些问题的一些方法


1

可能是在Unix / Linux环境中使用的默认编码。要检查当前哪种编码是默认编码,请执行以下操作:

$ echo $LANG
en_US

在这种情况下,我们可以清楚地看到它不是UTF-8编码,而是复制命令所依赖的编码。

因此,为了解决此问题,我们仅将example中的LANG变量设置为以下内容:

$ export LANG=en_US.UTF-8

注意:这仅适用于当前会话。将其添加到〜/ .bashrc或类似名称中,以使其在将来任何Shell会话启动时可用。

参考


1

我不建议在纯文本转储中盲目运行iconv,因为它可能会将有效字符(例如:汉字)转换为其他字符。最好通过运行以下命令来查找无效的UTF8字符。

grep -naxv '.*' plain_text_dump.sql

然后在特定数据上运行iconv。检查此文档以获取详细的逐步说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.