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

ped*_*nta 19 postgresql migration pgadmin

我的任务是将 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;
Run Code Online (Sandbox Code Playgroud)

我正在目标服务器上完全像这样创建这个数据库。但是当我使用“恢复”选项从 .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
Run Code Online (Sandbox Code Playgroud)

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

但这有点奇怪,因为使用 UTF8 不应该有这种问题,对吧?

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

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

提前致谢。

Ric*_*ard 8

在互联网上挖掘,我发现这是一个非常普遍的问题。常见的解决方案是使用纯文本格式转储并通过 iconv 提供它以纠正编码。

这里有更多相关信息。


Jac*_*las 7

“我不知道他们一开始是怎么到那里的”

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

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

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

=> 创建表 foo(t TEXT);

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

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

在这个优秀的博客上有一篇关于一般问题和一些处理方法的好帖子