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
    • 最新
    • 标签
主页 / server / 问题 / 462682
Accepted
user492160
user492160
Asked: 2013-01-04 09:05:54 +0800 CST2013-01-04 09:05:54 +0800 CST 2013-01-04 09:05:54 +0800 CST

恢复备份时出现mysql错误1062 'duplicate entry'

  • 772

抱歉,我看到了类似的帖子,但我仍然找不到它来解决我的问题另外,我需要更多关于这方面的信息。

要求:创建现有数据库“db3”的精确副本“db4”。

程序如下:

  • mysqldump -uuser -ppass db3 > db3.sql(大小为6G)
  • mysql -uuser -ppass db4 < db3.sql(db4 是新创建的空白数据库)

第二步抛出错误:

ERROR 1062 (23000) at line 5524: Duplicate entry '600806' for key 1"

我用 --force 再次运行了第二步。还原已完成,但还有 2 个类似的错误:

ERROR 1062 (23000) at line 6309: Duplicate entry '187694' for key 1    
ERROR 1062 (23000) at line 6572: Duplicate entry '1567400' for key 1

当我查询 db4 数据库的某些表时,我能够看到丢失的记录。

问题:

  1. 这是否表示 db3 数据库已损坏/有问题?

  2. 如何继续创建 db3 的“一致/工作”副本 (db4)?

谢谢,

debian-lenny
  • 3 3 个回答
  • 12663 Views

3 个回答

  • Voted
  1. Best Answer
    knoepfchendruecker
    2013-07-23T08:25:04+08:002013-07-23T08:25:04+08:00

    出现这种“重复”的原因有多种:

    • 你的数据是吐司。
    • 应用程序使用自动增量插入,但后来运行更新以手动将标识修改为不同的,可能是现有值。这有时会发生在应用程序开发人员“按 ID”排序并希望“修复排序”(通过实际破坏一致性)时。
    • 第二个问题的变体发生在那些后来在插入非唯一记录后添加“唯一”约束的人身上。

    错误消息确实引用了第一个键,在大多数数据库模式中它是第一个值。查看原始转储输出,尤其是 INSERT 语句并检查

    INSERT INTO ... values (0,...

    扫描错误消息中给出的 mysql 转储的行号。

    我期待什么样的 mysqldump 示例:

    INSERT INTO foo (id,bar,baz) values (1,2,3);
    INSERT INTO foo (id,bar,baz) values (0,4,5);
    INSERT INTO foo (id,bar,baz) values (2,6,7);
    

    在自动递增字段的“正常”INSERT 语句中,值“0”指定自动递增字段,因此不应出现在使用自动递增字段的数据库 SQL 转储中。通过 SQL 转储重新加载数据库,您的转储要求 SQL 服务器将当前字段值递增 1 并插入该 ID。如果有人在插入记录后手动将身份更新为零,您的 MySQL 转储也会包含这个奇怪的 ID。

    如果您将此转储重播到一个空表中,这将尝试创建以下记录:

    1,2,3
    2,4,5
    2,6,7
    

    由于“id”字段已设置为唯一自动增量,第二个 INSERT 将创建一个“错误”记录(预期:0,4,5;实际:2,4,5)与以下记录冲突(id = 2 ) 并因此给出错误消息。

    在这种变化中,有人“手动”将身份更新为一个已经存在的值,然后将记录更改为“唯一”。如果当前数据符合要求,将记录类型更改为唯一不会使 MySQL 重新验证,因此会出现延迟错误。此变体可能会创建如下转储:

    INSERT INTO foo (id,bar,baz) values (1,2,3);
    INSERT INTO foo (id,bar,baz) values (1,4,5);
    INSERT INTO foo (id,bar,baz) values (2,6,7);
    

    由于唯一约束,尝试插入第二行将失败。

    在这两种情况下,使用“--force”只会忽略“冲突”行并继续导入。“冲突”行将丢失,但可能会存在导致此冲突的行(但 ID 记录错误)。

    如果我的想法符合您的问题,请检查您的数据库转储。如果是这种情况,这里有两个解决方法来“让它工作”:

    • 分两步导入数据,首先是模式,然后是数据。在导入数据之前从模式中删除唯一约束,稍后再次添加唯一约束(“ALTER TABLE ... 添加唯一...”)。

    • 强制导入模式和所有数据,导致“不同”约束问题。手动检查哪些记录是正确的,并将错误的记录重新分配给它们的原始值。

    后一期的例子:

    mysql -uuser -ppass --execute "SET UNIQUE_CHECKS=0; source db3.sql" db4
    

    这确实会强制导入所有冲突的记录,甚至违反任何真正的唯一约束。导入后,您将拥有这三个记录(600806、187694 和 1567400)的多个条目,并且您必须通过检查转储来手动挑选出正确的条目,哪些“重复项”确实导致了冲突并手动将错误记录“回”更新为零(或转储中的冲突行所说的任何内容)。

    在这两种情况下,您的数据仍然违反给定的模式:您的模式说数据是唯一的,但事实并非如此。从长远来看,数据需要固定在应用程序级别。

    • 2
  2. Wing Tang Wong
    2013-04-10T13:21:24+08:002013-04-10T13:21:24+08:00

    首先,检查原始数据库中是否存在处于该状态的相关行。

    发生的情况很可能是以下情况之一:

    • 有问题的列/字段在某一点上不是唯一的,但后来被更改了。
    • 这是你正在转储的从数据库,在某些时候有一些 binlog 重放,并且插入了潜在的重复键
    • 错误的 SQL 语句或命令导入导致重复条目。

    如果只有 3 行显示问题,请更正它们的键字段,如果可能,执行该实例的转储和导入,看看错误是否不会再次出现。我猜,它应该消失了。

    • 1
  3. Sc0tTy
    2015-09-24T03:29:23+08:002015-09-24T03:29:23+08:00

    前言

    因此,在我们的一个复制服务器进入不一致状态后,我遇到了这个问题。我们无法通过快速修复使其恢复在线,因此决定使用新备份重新初始化复制。

    上面提到的问题不是同一个问题,但确实会返回相同的错误,因此我决定添加这个答案以防其他人正在寻找它。

    它也是DBA Stack Exchange上这个问题的完全重复,但是因为这个问题在(我的)Google 结果中排名更高,所以我也将它发布在这里。

    我们做了什么

    我们使用 MySQL Workbench 删除了实例上的所有数据库,我重新启动了实例并仔细检查了实例上没有数据库的地方。在主服务器上,我们已经开始使用我们一直使用的脚本创建新备份。

    然后一旦备份在故障服务器上,我们就开始导入,几个小时后它导入了大部分数据并因以下类型的错误而失败:

    ERROR 1062 (23000) at line XXX: Duplicate entry 'dbName-tblName' for key 'PRIMARY'
    Operation failed with exitcode 1
    

    我们想好吧,也许创建备份时出了问题,我检查了备份中的数据但没有发现任何错误。我们再次重试了所有步骤,以确保我们没有遗漏任何东西,但不幸的是没有雪茄。

    实际问题

    显示的错误不是实际插入数据而是创建索引。这就是为什么数据插入没有问题(我们检查过)但仍然产生错误的原因。显然删除所有表是不够的,索引数据仍然存在于服务器上(这可能是由于 MySQL 5.6 中的更改,因为我们以前从未遇到过这个问题)。而且因为这些索引的导入是在导入文件中间的某个地方,所以其余的数据没有被导入。

    修复

    我们删除了ibdata1文件和mysql数据库文件夹下的所有innodb_index_stats和innodb_table_stats文件,然后启动了实例。然后 MySQL 会告诉您缺少一些系统表, 您可以在此处找到更多相关信息

    这解决了我们的问题,我们的服务器现在正在按预期进行复制。

    希望这可以为某个地方的某人节省一些时间 :)

    • 1

相关问题

  • Lenny 网桥上的 Xen 3.2 损坏

  • 帮助!Wordpress 帖子返回 404(Debian + Apache)[关闭]

  • Debian Lenny 和 php4(连同 php5)

  • 从外部设备复制非常慢

  • 我应该如何将 debian/xen 机器从 etch 升级到 lenny

Sidebar

Stats

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

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

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

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve