Mysql大表添加字段失败解决方案

背景

最近遇到一个问题,需要在user用户表千万级别数据中添加两个字段,发现老是加不上去,一直卡死。表数据量不仅大,而且是一个热点表,访问频率特别高,而且该表的访问是在一个大事务中。加字段的时候一直在等待获取MDL写锁。这个等待也影响了后续表访问对MDL读锁的获取,导致后面的查询也都被堵塞了。更惨的是,客户端有重试机制,查询堵塞超过超时时间会再起一个session进行请求,导致数据库的线程池很快就爆满了,直接挂掉。

MDL锁

MDL锁介绍

MDL锁属于表级别的元数据锁表级别锁分为数据锁元数据锁,通常我们说的加锁一般指的是加的数据锁。跟数据锁一样,元数据锁也分读锁写锁

MDL不需要显示使用,在进行表操作时会自动加上。当对表数据进行增删改查( insert、delete、select、update等)时,会自动加上MDL读锁;当要对表进行加减字段的结构修改时,会自动加上MDL写锁

  • 读锁不互斥:意味着可以多个线程同时对一张表进行增删改查(CRUD)的操作。
  • 写锁独占:进行结构修改前,要先等待其他所有的MDL锁释放了才能获取到MDL写锁。获取到写锁后,在写锁释放前,其他线程无法获取到MDL读锁和写锁。也就是说,修改一个表的结构过程中,会阻塞其他线程对表的操作

MDL锁是MySQL自动隐式加锁,无需我们手动操作。在我们执行DML语句的时候,MySQL自动添加MDL读锁。在我们执行DDL语句的时候,MySQL自动添加MDL写锁。读锁与读锁之间不互斥,读锁与写锁、写锁与写锁之间互斥。注意:MDL锁是表锁,会对整张表加锁

  • DML(Data Manipulation Language)数据操纵语言:适用范围:对表数据进行操作,比如 insert、delete、select、update等。
  • DDL(Data Definition Language)数据定义语言:适用范围:对表结构进行操作,比如create、drop、alter、rename、truncate等。

MDL锁的必要性

MDL锁 的存在,其实是为了保证 数据的一致性 。想象一下,假如没有 MDL锁 ,一个查询在遍历表数据的过程中,另外一个线程执行了ALTER TABLE t DELETE COLUMN 'col_1'把col_1这一列删掉了,那查询结果就乱了,结果中是否应该有这一列数据?所以为了保证并发操作下数据的一致性。如果一个事务正在执行中,另一个在这时修改了表结构,不但可能导致当前事务出现不可重复读的问题,还有可能连事务都无法提交

事故复现

介绍完MDL锁,我们再来复现下事故。我们通过下面的操作序列来模拟线上情况。

Session 1Session 2Session 3
begin;
select * from user limit 10;
alter table user add ‘age’ int not null default ‘0’ comment ‘年龄’;
(阻塞)
select * from user limit 10;

时刻1,事务1对表user进行查询,注意此时事务1并未提交,所以获取的MDL读锁也不会释放。时刻2另外一个线程想要添加字段, 由于 事务1正持着MDL读锁,所以事务2会陷入阻塞,等待事务1释放读锁后获取MDL写锁

申请 MDL 锁的操作会形成一个队列,队列中写锁获取优先级高于读锁
所以事务2不仅阻塞了加字段的操作,也会阻塞后续对该表的所有操作。比如后面的事务3查询由于获取不到MDL读锁都被阻塞了

这时,如果客户端有重试机制,查询超时后会重新进行请求,容易把数据库的连接池给挤爆了。

Mysql服务宕机的原因

为什么会出现这种情况呢?
原因是在执行查询语句的时候,MySQL自动加了MDL锁(metadata lock,即元数据锁)
不行的话,我们可以再执行一下show processlist命令,查看有哪些正在执行的进程:
在这里插入图片描述
可以清楚的看到Session2和Session3的语句正在等待MDL锁,Waiting for table metadata lock

解决方案

  • 方案一:
    了解了原因,事情就比较好处理了,数据库奔溃原因是由于加字段等待时间太长导致影响后续请求,但mysql又无法在 alter table 语句里面设定等待时间。
    所以当时做法是继续尝试加字段语句,语句卡住30秒就手动cancel掉。避免对后续请求的影响。重试了几次发现一直没能加上。最后是通过查看接口调用监控,在请求频率较低的时间点给加上了。

  • 方案二:
    从MySQL5.6版本开始增加了Online DDL,作用就是在执行DDL的时候,允许并发执行DML。简单翻译就是修改表结构的时候,也能同时支持并发执行增删查改操作。从MySQL8.0版本开始又优化了Online DDL,支持快速添加列,可以实现给大表秒级加字段。具体用法就是在DDL语句后面增加两个参数ALGORITHMLOCK。比如下面这样:
    ALTER TABLE user ADD age int NOT NULL DEFAULT '0' COMMENT '年龄', ALGORITHM=Inplace, LOCK=NONE;

    ALGORITHM可以指定使用哪种算法执行DDL,可选项有:

    • Copy:拷贝方式,MySQL5.6 之前 DDL 的执行方式,过程就是先创建新表,修改新表结构,把旧表数据复制到新表,删除旧表,重命名新表。执行过程非常耗时,产生大量的磁盘IO和占用CPU,还有使Buffer poll失效,而且需要锁住旧表,性能较差,现在基本很少使用。
    • Inplace:原地修改,MySQL5.6开始引入的,优点是不会在Server层发生表数据拷贝,过程中允许并发执行DML操作。过程就是先添加MDL写锁,执行初始化操作,然后降级为MDL读锁,执行DDL操作(比较耗时,允许并发执行DML操作),升级为MDL写锁,完成DDL操作。
    • Instant:快速修改,MySQL8.0开始引入的,可以实现快速给大表添加字段。

    性能依次是,Instant > Inplace > Copy。

    LOCK可以指定执行过程中,是否加锁,可选项有:

    • NONE不加锁,允许DML操作。
    • SHARED加读锁,允许读操作,禁止DML操作。
    • DEFAULT默认锁模式,在满足DDL操作前提下,默认锁模式会允许尽可能多的读操作和DML操作。
    • EXCLUSIVE加写锁,禁止读操作和DML操作。

其他

这里我们重点关注INNODB_TRX, INNODB_LOCKS, 以及INNODB_LOCK_WAITS三张表,表如其名,这三张表记录了正在运行的事务(包括事务占用or释放锁的信息)状态信息

select * FROM information_schema.INNODB_TRX;
select * FROM information_schema.INNODB_LOCKS;
select * FROM information_schema.INNODB_LOCK_WAITS;

desc information_schema.INNODB_TRX;
desc information_schema.INNODB_LOCKS;
desc information_schema.INNODB_LOCK_WAITS

show engine innodb status;
show processlist;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue3大事件项目(ing)

文章目录 核心内容1.大事件项目介绍2.大事件项目创建3.Eslint配置代码风格4.配置代码检查工作流问题: pnpm lint是全量检查,耗时问题,历史问题 5.目录调整6.vue-router4 路由代码解析7.引入 Element Plus 组件库8.Pinia 构建仓库 和 持久化9.Pinia 仓库统一管理 核心内容 Vue3…

CX341A 安装驱动与刷固件

参考 驱动安装1 DPDK编译:支持Mellanox 25Gbps网卡 - 知乎 NVIDIA Mellanox CX网卡固件、驱动系列操作 - 知乎 驱动安装2 Mellanox网卡驱动安装指南 Mellanox OFED_崇尚匀速 追求极致的技术博客_51CTO博客 驱动与固件: 家用万兆网络指南 6 - 比…

3、生成式 AI 如何帮助您改进数据可视化图表

生成式 AI 如何帮助您改进数据可视化图表 使用生成式 AI 加速和增强数据可视化。 图像来源:DALLE 3 5 个关键要点: 数据可视化图表的基本结构使用 Python Altair 构建数据可视化图表使用 GitHub Copilot 加快图表生成速度使用 ChatGPT 为您的图表生成相关内容使用 DALL-E 将…

JCTC | 利用几何深度学习对蛋白质-配体结合pose进行等变灵活建模

Overview 该论文解决了药物开发中蛋白质-配体复合结构灵活建模的挑战。作者提出了一种名为FlexPose的新型深度学习框架,它可以直接对复杂结构进行建模,而不需要传统的采样和评分策略。 该模型结合了标量-向量双特征表示和 SE(3)等变网络设计来处理动态结…

[word] word表格内容自动编号 #经验分享#微信#其他

word表格内容自动编号 在表格中的内容怎么样自动编号?我们都知道Word表格和Excel表格有所不同,Excel表格可以轻松自动编号,那么在Word表格中如何自动编号呢? 1、选中内容后,点击段落-自动编号,选择其中一…

基于SSM的实习管理系统(有报告)。Javaee项目。ssm项目。

演示视频: 基于SSM的实习管理系统(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring Spri…

【MATLAB】使用梯度提升树在回归预测任务中进行特征选择(深度学习的数据集处理)

1.梯度提升树在神经网络的应用 使用梯度提升树进行特征选择的好处在于可以得到特征的重要性分数,从而识别出对目标变量预测最具影响力的特征。这有助于简化模型并提高其泛化能力,减少过拟合的风险,并且可以加快模型训练和推理速度。此外&…

首个商业化的可用于神经退行性疾病研究的即用型SMN ELISA试剂盒

首个商业化的可用于神经退行性疾病研究的即用型SMN ELISA试剂盒 运动神经元生存蛋白(SMN)是一种约38kDa的蛋白质,主要由位于5q染色体端粒部分的SMN1基因产生。几乎相同的着丝粒拷贝(SMN2)也产生少量的全长SMN蛋白&…

大规模机器学习简介

1. 非线性回归问题 1.1 问题描述 我们有一组实验数据,每个实验都给出了输入和输出对 (Xn, Yn)。每个输入 是空间中的一个点,每个输出 是 空间中的一个点。这些数据点被假设为独立同分布(i.i.d)。 我们的目标是找到一个函数 fw&…

即插即用、简单有效的大语言模型推荐算法!港大联合百度推出RLMRec

论文链接: https://arxiv.org/abs/2310.15950 论文代码: https://github.com/HKUDS/RLMRec 实验室主页: https://sites.google.com/view/chaoh/group-join-us?authuser0 TLDR 本文从互信息最大化的理论角度出发,通过引入文本信号…

微信小程序的图片色彩分析,窃取主色调,调色板

1、在微信小程序中创建包管理器 package.json npm init -y 2、安装 Mini App Color Thief 包 npm i --save miniapp-color-thief 3、构建 npm 4、wxml <canvas canvas-id"myCanvas"></canvas> <button bindtap"chooseImage">chooseIm…

构造函数

1.构造基本概念 1.是成员函数的一种&#xff0c;名字与类名相同&#xff0c;可以有参数&#xff0c;不能有返回值&#xff08;void也不行&#xff09; 作用是对对象进行初始化&#xff0c;如给成员变量赋初值 2.如果定义类是没写构造函数&#xff0c;则编译器生成一个默认的…

在 Docker 中启动 ROS2 里的 rivz2 和 rqt 出现错误的解决方法

1. 出现错误&#xff1a; 运行 ros2 run rivz2 rivz2 &#xff0c;报错如下 &#xff1a; No protocol specified qt.qpa.xcb: could not connect to display :1 qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was f…

debian12 - openssh-9.6.P1的编译安装

文章目录 debian12 - openssh-9.6.P1的编译安装概述笔记备注END debian12 - openssh-9.6.P1的编译安装 概述 在debian12上, 源码编译安装了openssl3.2 导致ssh失败. lostspeeddebian12d4x64:~$ openssl version OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2…

金融信贷风控系统设计

前言 近一年多以来在金融行业负责风控系统&#xff0c;根据自己工作中的经验&#xff0c;写下这篇文章。既是对自己在风控领域工作的总结&#xff0c;也是给刚入行和准备入行的朋友打个样&#xff0c;希望能有所帮助。 为什么要有风控系统 记得 2016 年信贷行业的发展形势还…

计算机毕业设计 基于SpringBoot的城市垃圾分类管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

深入解析 Spring 事务机制

当构建复杂的企业级应用程序时&#xff0c;数据一致性和可靠性是至关重要的。Spring 框架提供了强大而灵活的事务管理机制&#xff0c;成为开发者处理事务的首选工具。本文将深入探讨 Spring 事务的使用和原理&#xff0c;为大家提供全面的了解和实际应用的指导。 本文概览 首…

​​​​​​​CleanMyMac X有什么优势?到底好不好用?

当你的Mac开始变得缓慢或者存储空间告急时&#xff0c;这通常是一个清理磁盘空间的信号。无论是工作文件、个人照片、还是各种应用程序&#xff0c;随着时间的推移&#xff0c;它们都可能在你的硬盘上积累了大量数据。有效地管理这些文件不仅可以提高你的工作效率&#xff0c;还…

DevExpress WinForms中文教程 - 如何创建可访问的WinForms应用?(二)

为用户创建易访问的Windows Forms应用程序不仅是最佳实践的体现&#xff0c;还是对包容性和以用户为中心的设计承诺。在应用程序开发生命周期的早期考虑与可访问性相关的需求可以节省长期运行的时间(因为它将决定设计决策和代码实现)。 一个可访问的WinForms应用程序提供了各种…

Android 11 访问 Android/data/或者getExternalCacheDir() 非root方式

前言&#xff1a; 需求要求安装三方应用ExternalCacheDir()下载下来的apk文件。 getExternalCacheDir() : /storage/emulated/0/Android/data/com../cache/ 获取访问权限 如果手机安卓版本为Android10的时候,可以在AndroidManifest.xml中添加下列代码 android:requestLegacyExt…