AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 4777
Accepted
pedrosanta
pedrosanta
Asked: 2011-08-19 09:38:00 +0800 CST2011-08-19 09:38:00 +0800 CST 2011-08-19 09:38:00 +0800 CST

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

  • 772

我的任务是将 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;

我正在目标服务器上完全像这样创建这个数据库。但是当我使用恢复选项从 .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,以便在执行还原时不会遇到任何问题?

提前致谢。

postgresql migration
  • 5 5 个回答
  • 169538 Views

5 个回答

  • Voted
  1. Best Answer
    Richard
    2011-08-19T11:09:00+08:002011-08-19T11:09:00+08:00

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

    这是有关此的更多信息。

    • 8
  2. Jack Douglas
    2011-08-19T13:59:46+08:002011-08-19T13:59:46+08:00

    “我不知道他们最初是如何到达那里的”

    它可能会按照此处所述发生- 尽管这会在 8.4 上产生错误:

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

    例如,如果你有一个 UTF8 编码的数据库,你可以这样做:

    => 创建表 foo(t 文本);

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

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

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

    • 7
  3. Nijil
    2019-06-05T22:07:05+08:002019-06-05T22:07:05+08:00

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

    grep -naxv '.*' plain_text_dump.sql
    

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

    • 3
  4. arulraj.net
    2014-08-14T16:59:53+08:002014-08-14T16:59:53+08:00

    它可能与您的 Unix/Linux 环境中使用的默认编码有关。要检查当前的默认编码是哪种编码,请执行以下命令:

    $ echo $LANG
    en_US
    

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

    因此,为了解决这个问题,我们只需将示例中的 LANG 变量设置为以下内容:

    $ export LANG=en_US.UTF-8
    

    注意:这仅适用于当前会话。将其添加到 ~/.bashrc 或类似文件中,以便在将来的任何 shell 会话启动时使用它。

    参考

    • 1
  5. Biswajit Barman
    2020-02-07T05:58:12+08:002020-02-07T05:58:12+08:00

    我引用了以下链接,它为我提供了确定源编码然后将其转换为所需的 UTF-8 编码的线索。 Linux 检查和更改编码

    $ file -bi cabot.sql
    text/plain; charset=utf-16le
    $ iconv -f utf-16le -t utf-8 -o converted.sql cabot.sql
    $ file -bi converted.sql
    text/plain; charset=utf-8
    
    • 0

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve