Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL add/drop字段时报主键冲突

MySQL add/drop字段时报主键冲突

作者头像
用户1278550
发布于 2019-10-13 07:29:50
发布于 2019-10-13 07:29:50
5K00
代码可运行
举报
文章被收录于专栏:idbaidba
运行总次数:0
代码可运行

问题现象

很多DBA朋友做ddl 变更比如添加、删除字段时,一定概率上会遇到如下报错:

Duplicate entry '7458421' for key 'PRIMARY'

错误提示是主键冲突,但是当我们去查询 id= 7458421 时,并无此记录。是不是很奇怪?遇到这种情况,一般有如下场景:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1  表具有一个或者多个唯一键。2  表比较大,执行DDL耗时超过数十秒。3  表的insert 操作比较频繁。
问题分析

首先我们通过一个思维导图了解一下MySQL online DDL 的过程,大家注意commit阶段,会把ddl 执行期间的记录的 log 重新应用到新的表上。

从官方文档中的描述所说 online ddl 期间,其他会话执行的dml操作造成唯一键冲突的sql会记录到 online log 中,在commit阶段等变更结束之后再应用这些sql会导致报错唯一键冲突。

When running an online DDL operation, the thread that runs the ALTER TABLE statement applies an online log of DML operations that were run concurrently on the same table from other connection threads. When the DML operations are applied, it is possible to encounter a duplicate key entry error (ERROR 1062 (23000): Duplicate entry), even if the duplicate entry is only temporary and would be reverted by a later entry in the online log. This is similar to the idea of a foreign key constraint check in InnoDB in which constraints must hold during a transaction.

问题复现

构造一个2000w记录的表,其表结构如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE `ddl` (  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  `c1` int(10) NOT NULL DEFAULT '0',  `c2` int(10) unsigned NOT NULL DEFAULT '0',  `c3` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  PRIMARY KEY (`id`),  UNIQUE KEY `c2` (`c2`),  KEY `idx_c1` (`c1`)) ENGINE=InnoDB AUTO_INCREMENT=20000001 DEFAULT CHARSET=utf8mb4

举一反三 ,其实只要是会导致重复记录的sql语句,比如update,insert,insert into... on duplicate key,replace into 都会导致添加字段、删除字段的ddl变更失败。

如何解决呢 ,推荐使用 pt-osc或者 gh-ost 在线ddl变更工具

官方的讨论

官方定对于该问题是online ddl的限制,有兴趣的朋友可以阅读下面两个链接,了解官方和提交问题人员的讨论记录。

https://bugs.mysql.com/bug.php?id=76895

https://bugs.launchpad.net/percona-server/+bug/1445589

关联知识

innodb_online_alter_log_max_size 是MySQL 5.6版本引入。该参数限定了online ddl操作时使用的临时日志文件的最大大小。在创建索引或者对表进行alter操作时,该日志文件存储了DDL操作期间对表的 insert,update,delete的数据记录。临时日志文件每次以 innodb_sort_buffer_size 为单位进行扩展直至达到 innodb_online_alter_log_max_size设置的最大值。如果临时日志的大小超出规定限,则online ddl操作失败,当前所有未提交的DML操作会回滚。该参数设置日志文件太大带来的负面影响是可能会导致DDL操作最后锁定表(Waiting for table metadata lock)的时间更长,因为要花费更长的时间应用日志到表上。所以涉及到dml比较频繁的表的ddl 尽量放到业务低峰操作。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yangyidba 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL 实战笔记 第03期:MySQL Online DDL 三阶段初探
上一节咱们了解了元数据锁,但在 Online DDL 操作中具体是怎样加锁的呢?加几次锁呢?带着这些疑问,我们一起来学习 DDL 三阶段。
数据库交流
2022/04/25
6190
MySQL 实战笔记 第03期:MySQL Online DDL 三阶段初探
MySQL之Online DDL再探
昨天内容中说了MySQL5.6引入了online DDL,但是没有详细的展开说,这块儿内容比较多,只能一点一点的写了,今天再来看这里的内容。
AsiaYe
2020/01/15
9560
MySQL之Online DDL再探
MySQL Online DDL
serena
2017/06/01
8K0
MySQL Online DDL
MySQ之onlineDDL
COPY是MYSQL 5.5以及之前的默认算法,使用COPY算法会锁表,不支持online ddl,COPY算法在server层创建一个临时表用于copy数据,最后用新表替换旧表。
leobhao
2024/08/27
1280
MySQ之onlineDDL
DDL 失败案例一则
今天对线上某个业务的大表120G进行重建表操作时遇到报错,该表有个比较显著的特征是*写入量比较大,每天写入加更新的频率在数千万级别。大致的环境
用户1278550
2018/08/09
1.7K0
故障分析 | MySQL 执行 Online DDL 操作报错空间不足?
作者:徐文梁,爱可生 DBA 成员,一个执着于技术的数据库工程师,主要负责数据库日常运维工作。擅长 MySQL,Redis 及其他常见数据库也有涉猎;喜欢垂钓,看书,看风景,结交新朋友。
爱可生开源社区
2024/02/21
3000
故障分析 | MySQL 执行 Online DDL 操作报错空间不足?
MySQL谬误集02: DDL锁表
导语 | 本文是MySQL谬误集系列文章的第二篇,该系列旨在纠正一系列似是而非的说法。比如关于MySQL DDL操作,有很多同学认为会锁表,那是不是一定会锁表呢?是锁读还是锁写呢?锁多长时间?不同的DDL操作有差别吗?MySQL从5.5到8.0,对这个问题有什么改进呢?本文做了一个简单的总结。
DBA成江东
2023/08/19
1.6K0
MySQL谬误集02: DDL锁表
MySQL之Online DDL过程
昨天内容中说了不同类型的DDL操作所采用的的执行方法,以及Online DDL对系统空间的依赖,今天我们说说Online DDL的操作过程,让大家有一个更加直观的认识。
AsiaYe
2020/01/15
2.7K0
MySQL之Online DDL过程
Mysql onlineddl vs gh-ost
Innodb早期支持通过copy table跟inplace的方式来执行DDL语句,其原理如下:
mingjie
2022/05/12
8690
Mysql onlineddl vs gh-ost
技术分享 | 可能是目前最全的 MySQL 8.0 新特性解读(上)
系统表全部换成事务型的innodb表,默认的MySQL实例将不包含任何MyISAM表,除非手动创建MyISAM表。
爱可生开源社区
2023/03/23
1.6K0
MySQL DDL发展史
- 注意: 在online ddl前,inplace的方法主要在第三步大大缩短了时间,只重构了索引,没有重新copy所有数据
划水教练
2022/05/17
1.1K0
MySQL DDL发展史
MySQL 8.0.19亿级数据如何秒速增加字段?
今天主要介绍一下MySQL 8.0.19 instant add column的新特性,基于亿级数据秒速增加字段,下面一起来看看吧~
IT大咖说
2021/03/14
8K0
聊聊 MySQL 的 Online DDL
日常开发我们对一条DML语句较为熟悉,很多开发人员都了解sql的执行过程,比较熟悉,但是DDL是如何执行的呢,大部分开发人员可能不太关心,也认为没必要了解,都交给DBA吧。其实不然,了解一些能尽量避开一些ddl的坑,那么下面带大家一起了解一下DDL执行的方式,也算抛砖引玉吧。如有错误,还请各位大佬们指正。
码猿技术专栏
2023/09/07
1.1K0
聊聊 MySQL 的 Online DDL
MySQL DDL详情揭露
MySQL中DDL语句,即数据定义语言,用于创建、删除、修改、库或表结构,对数据库或表的结构操作。常见的有create,alter,drop等。这类语句通常会耗费很大代价,特别是对于大表做表结构变更。本篇文章会揭露各类DDL语句执行的详细情况。
MySQL技术
2020/02/19
1.3K0
Online DDL和Cardinality
Mysql 5.5版本之前,当我们对数据库索引进行添加或删除这类DDL操作,Mysql数据库的操作过程为:
大忽悠爱学习
2022/12/13
5490
Online DDL和Cardinality
MySQL主键自增值为什么有“空洞”?
本文在测试 insert、insert ignore、replace into 三种数据插入方式的时候,发现插入数据的时候在表内存在带有“唯一特性”的值重复的情况下三种语句的处理方式。最终发现了MySQL主键自增值“空洞”了
GreatSQL社区
2023/02/23
2.4K0
开发经验|小白该如何学习MySQL配置文件
上一篇简单介绍了下MySQL的存储引擎,为什么需要存储引擎以及如何使用存储引擎。MySQL的配置文件是控制和配置 MySQL服务器行为的重要文件。对于新手开发者来说,理解掌握并运用 MySQL 配置文件是非常重要的。本篇想着重讲下MySQL的配置文件,帮助读者朋友们快速了解并上手使用,以便解决你在学习和工作中遇到的问题。
六月暴雪飞梨花
2023/11/24
8610
开发经验|小白该如何学习MySQL配置文件
大表Online-DDL操作问题初探
今天下午在执行一个表结构变更的时候,出现了一个问题,拿着分析了分析,对于online-ddl又有了新的认识,这里写篇文章记录下。
AsiaYe
2020/01/22
1.6K0
MySQL之重建表
在MySQL中,如果我们对大表频繁进行insert和delete操作,那么时间一长,这个表中会出现很多"空洞",也就是表碎片。
AsiaYe
2020/07/01
4.5K0
基于goinception搭建DBA审核平台
使用过inception的人对SQL审核这块获取都比较熟悉,作为DBA,审核SQL是日常工作中的很重要的一块内容,审核好SQL对于后期项目以及数据库维护上起着至关重要的作用。
IT大咖说
2020/11/10
2.5K0
基于goinception搭建DBA审核平台
相关推荐
MySQL 实战笔记 第03期:MySQL Online DDL 三阶段初探
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验