MySQL 在线 DDL 变更的一个异常问题

文章目录

    • 前言
    • 1. 模拟现场
    • 2. 原因推测
    • 3. 如何解决
    • 4. 误导报错
    • 后记

前言

业务执行一条 DDL engine=innodb 失败了很多次,报错 ERROR 1062 (23000): Duplicate entry xxx for key ‘xxx’,在官方文档中也提到过,Online DDL 期间可能会出现 ERROR 1062 (23000): Duplicate entry 异常,但是没有详细说明,什么情况下会触发。业务执行 DDL 的时候,一直没有成功,意味着距离找到答案不远了。

When running an in-place 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.
https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-limitations.html

1. 模拟现场

创建测试表结构:

CREATE TABLE `ddl_test` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`user_id` bigint(20) NOT NULL,`channel_id` tinyint(4) NOT NULL,`version` bigint(20) NOT NULL,`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`user_info` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `unq_index` (`user_id`,`channel_id`,`version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

制造测试数据,便于观测问题现象:

mysql_random_data_load -h127.0.0.1 -u'test' -p --max-threads=10 test ddl_test 2000000

PS:如何造数,可参考之前文章:MySQL 快速造数 mysql_random_data_load

  1. 手动插入一行记录,接下来打开两个会话窗口。
insert into ddl_test(user_id, channel_id, version,  user_info) value (19, 10, 2200, 'abc');
  1. Session 1:执行 Online DDL 变更。
alter table ddl_test engine=innodb, ALGORITHM=INPLACE, LOCK=NONE;
  1. Session 2:再次执行步骤 1 的写入,由于违反了 unq_index 约束会抛出异常:
root@mysql [test]>insert into ddl_test(user_id, channel_id, version,  user_info) value (19, 10, 2200, 'abc');
ERROR 1062 (23000): Duplicate entry '19-10-2200' for key 'unq_index'
  1. Session 1:DDL 执行到最后阶段,合并增量日志时,抛出异常,执行失败。
root@mysql [test]>alter table ddl_test engine=innodb, ALGORITHM=INPLACE, LOCK=NONE;
ERROR 1062 (23000): Duplicate entry '19-10-2200' for key 'unq_index'

这里会让人疑惑的是,在步骤 3 上面,插入并没有执行成功,为什么会导致 DDL 执行失败呢?

2. 原因推测

MySQL Online DDL 会记录增量日志,然后再最后阶段会把 DDL 期间的写入合并到表中,经过观察 DDL 总在执行一段时间后,报错,并不是重复写入失败后,DDL 立即失败的。所以推测是在合并阶段,增量写入,包含执行失败的回滚的事务,全部合并到表里,从而导致 DDL 执行失败。

3. 如何解决

了解到业务是一个并发写入的场景,会偶发导致重复写入的问题,定位到业务场景后,通过降低了并发,减少了重复写入。最后 DDL 执行成功。如果遇到该问题,建议先定位问题是由于哪些 SQL 造成的,然后和业务侧配合规避掉这个异常。个人觉得是一个 bug,并使用 8.4 版本进行了测试,发现依然执行失败。

4. 误导报错

经过测试在 MySQL 5.7.17 版本复现该问题的时候,会出现一个误导报错。虽然是由 unq_index 约束造成的,在 DDL 会话里面,会直接报错主键的值,并且这个自增主键值不存在,因为已经被回滚了,回滚后自增主键不会重新分配了,会让用户一头雾水。

root@mysql  [deom]>alter table ddl_test engine=innodb, ALGORITHM=INPLACE, LOCK=NONE;
ERROR 1062 (23000): Duplicate entry '200006' for key 'PRIMARY'

后记

后面计划有时间使用 GDB 调试一下 MySQL 找找代码里面的原因,或者如果各位知道原因可以分享在评论区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/63700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式事务的前世今生-纯理论

一个可用的复杂的系统总是从可用的简单系统进化而来。反过来这句话也正确: 从零开始设计的复杂的系统从来都用不了,也没办法让它变的可用。 --John Gal 《系统学》 1975 1. 事务的概念 百科: 事务(Transaction),一般是…

微前端框架micro-app中的数据通信机制

在微前端框架micro-app中,getData方法和addDataListener方法都是用于数据通信的重要工具,但它们在使用方式和功能上存在一些显著的差别。 getData方法 功能:getData方法用于直接获取micro-app框架注入的全局对象window.microApp中存储的数据…

操作系统的文件系统

文件系统的基本组成 ⽂件系统是操作系统中负责管理持久数据的⼦系统,说简单点,就是负责把⽤户的⽂件存到磁盘硬件中, 因为即使计算机断电了,磁盘⾥的数据并不会丢失,所以可以持久化的保存⽂件。 ⽂件系统的基本数据单位…

vue使用百度富文本编辑器

1、安装 npm add vue-ueditor-wrap 或者 pnpm add vue-ueditor-wrap 进行安装 2、下载UEditor 官网:ueditor:rich text 富文本编辑器 - GitCode 整理好的:vue-ueditor: 百度编辑器JSP版 因为官方的我没用来,所以我自己找的另外的包…

浅谈自然语言处理技术(NLP)在银行领域的应用

自然语言处理技术(NLP)通过解析和理解海量非结构化数据,为银行领域提供了前所未有的洞察力和决策支持。这项技术的应用不仅优化了风险管理,还革新了客户服务和市场分析等多个方面。 银行系统中存在大量的非结构化信息,这些信息不仅数据量庞大,而且种类繁多,处理起来相对…

nvm安装指定版本显示不存在及nvm ls-remote 列表只出现 iojs 而没有 node.js 解决办法

在使用 nvm install 18.20.3 安装 node 时会发现一直显示不存在此版本 Version 18.20.3 not found - try nvm ls-remote to browse available versions.使用 nvm ls-remote 查看可安装列表时发现,列表中只有 iojs 解决方法: 可以使用以下命令查看可安装…

算法基础 -- 背包问题类型与算法整理

背包问题类型与算法整理 1. 背包问题类型与描述 背包问题类型问题描述0-1 背包问题每种物品只能选择一次,求如何选择物品使得总价值最大。完全背包问题每种物品可以选择多次,求如何选择物品使得总价值最大。多重背包问题每种物品选择次数有限&#xff…

Linux磁盘存储概念(六)

本文为Ubuntu Linux操作系统- 第六弹 今天开始新的知识点,讲磁盘存储问题 上期回顾:Linux文件、目录权限问题 今天由帝皇侠陪伴大家学习!!! 文章目录 磁盘数据组织低级格式化磁盘分区高级格式化 磁盘设备命名磁盘分区分…

鼠标右键单击Git Bash here不可用

最近在学习git时突然发现右键的git bash没反应,但是去点击应用图标就能正常运行,通常是因为你在安装git之后改变了它的目录名称或者位置,我就是因为安装后改变了一个文件夹的文件名导致不可用 在安装git时系统会默认给鼠标右键选项的git Bas…

DApp开发如何平衡性能与去中心化?

DApp的核心价值在于信任、透明和去中心化,但这些特点往往伴随着性能的瓶颈和高成本。在DApp开发中,如何在保证去中心化的前提下提升性能,成为开发者面临的重要挑战。如何实现性能与去中心化的平衡是一个重要课题。 一、为什么去中心化影响性…

计算机网络之NAT、代理服务、内网穿透、内网打洞

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 计算机网络之NAT、代理服务、内网穿透、内网打洞 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记,欢迎大家在评论区交流讨论…

在 Vite 和 Webpack 中处理 SVG 图标:vite-plugin-svg-icons 与 svg-sprite-loader 原理比较

在 Vite 和 Webpack 中处理 SVG 图标:vite-plugin-svg-icons 与 svg-sprite-loader 原理比较 SVG 图标是前端开发中常用的资源,它不仅能提供更清晰的显示效果,还能通过 CSS 控制颜色和大小。随着现代构建工具如 Vite 和 Webpack 的普及&…

大数据新视界 -- 大数据大厂之 Hive 数据导入:多源数据集成的策略与实战(上)(3/ 30)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

VUE 搭建一个脚手架

一、安装 Node.js 、 npm、Vue Cli node -v npm -v npm install -g vue/cli vue --version // 查看是否安装成功 二、 创建项目 起名 vue create my-vue-project 三、项目目录 cd my-vue-project npm install // 如果没有自动安装,手动安装下依赖 四、启动项目 n…

Python中的 `string.Template`:用法和使用场景

Python中的 `string.Template`:用法和使用场景 什么是 `string.Template`?`Template` 的基本用法代码解析使用 `safe_substitute`实用场景1. 动态生成消息2. 生成文件内容如何处理复杂场景?总结在Python中,字符串处理是非常常见的任务,其中string.Template提供了一种简单、…

光猫开DMZ教程

本教程以移动光猫未例,具体操作以实际光猫为准 1、登录移动光猫管理后台 打开浏览器,在浏览器地址栏输入移动光猫登录管理地址192.168.1.1或者tplogin.cn 按“回车键”打开登录页面,然后输入路由器管理密码登录。 移动光猫登录页面 超级密…

分数求和ᅟᅠ        ‌‍‎‏

分数求和 C语言代码C 代码Java代码Python代码 💐The Begin💐点点关注,收藏不迷路💐 输入n个分数并对他们求和,并用最简形式表示。所谓最简形式是指:分子分母的最大公约数为1;若最终结果的分母为…

优秀前端文章笔记----持续更新

AI相关: 【介绍了RAG】万字长文分享AI落地前端实操,带你成为公司最懂AI的前端大佬!【介绍了提示词】面向前端人的提示词工程指南【介绍了AI IDE】打造一个 Cursor 只需要三步 工具相关: AI-magic收录了大量国内外AI工具箱&#…

vue-生命周期

Vue 的生命周期是指 Vue 实例从创建到销毁期间经历的一系列阶段。每个阶段都有相应的钩子函数(Lifecycle Hooks),允许开发者在这些关键时刻执行自定义逻辑。 一、钩子函数 1. 创建阶段 beforeCreate 在实例初始化之后,数据观测 …

SpringBoot中的@Configuration注解

在Spring Boot中,Configuration注解扮演着非常重要的角色,它是Spring框架中用于定义配置类的一个核心注解。以下是Configuration注解的主要作用: 定义配置类: 使用Configuration注解的类表示这是一个配置类,Spring容器…