一、MDL元数据锁

在修改表结构之前,先来看下可能存在的问题。

1、什么是MDL锁

MySQL有一个把锁,叫做MDL元数据锁,当对表修改的时候,会自动给表加上这把锁,也就是不需要自己显式使用。

  • 当对表做增删改查的时候,加的是MDL读锁
  • 当对表结构做变更修改的时候,加的是MDL写锁

读与读之间不互斥,读与写,写与写之间互斥,因此

  • 当有一个线程对表执行增删盖茶的时候,会阻塞掉别的线程对表结构修改的请求
  • 当有一个线程对表结构修改的时候,会阻塞掉别的线程对表增删改查的请求

2、MDL锁的问题

并且MDL一旦上锁之后,只有当前请求的事务提交才会释放,如果是一个长事务,或者是线上数据量很大,修改表结构默认上了MDL写锁,会很耗时一直阻塞掉后边其他请求。

想象一种场景,A(select),B(alter), C(select),D(select).....分别为按照顺序对MySQL同一张表的请求,这些请求会形成一个队列。

当A(select)获取表的MDL读锁之后,就会阻塞掉B(alter),因为B要加的是MDL写锁,B被阻塞掉之后,就会导致后边等待队列中的其他请求都被阻塞掉,最终造成Mysql的可用连接耗尽,请求超时等问题。

二、如何线上修改MySQL表结构

鉴于以上MDL锁,得知对表做alter修改结构很会阻塞掉其他的正常请求,所以修改操作要放在非业务高峰期来做,一般是放到凌晨2-4点。

具体步骤:

  • 对表加读写锁,使得此时表只读、
  • 复制原表的物理结构
  • 修改新表的物理结构,包括增加新字段或者修改其他表结构
  • 把表结构导入新表,数据同步完成,锁住中间表,删除原表
  • 将新表rename为原表名
  • 释放锁

以上方案的问题是,数据量很大的时候,数据都导入需要时间,这个过程中,服务是不可访问的。

改进:

新建一张表 A_new,其比原表多了几个字段,通过数据订阅的方式订阅原表A,把线上的表A中的数据同步到这个新建的表A_new中,这个过程会一直持续,并且这个过程中表A是可以增删改查的,总有一个时刻,这两张表的数据是完全同步的,数据上是没有任何差异的,这个时候把原表表名A给修改掉,把新表A_new修改为原表A,这个操作是一个短暂操作,可以瞬间完成,不会有很大影响。

优缺点:

  • 好处是同步的过程不会影响原有的业务正常。
  • 缺点是过程中需要额外一倍的存储空间去存储这个新表,当rename完成之后,可以把老表删掉。

MySQL数据库如何线上修改表结构的更多相关文章

  1. MySQL 分区表 partition线上修改分区字段,后续进一步学习partition (1)

    公司线上在用partition,有一个表的分区字段错了,需要重建,结果发现没有办法像修改主键字段或者修改索引字段那样直接一条sql搞定.而是需要建临时表,有down time,所以去仔细看了文档,研究 ...

  2. MySQL数据库 外键,级联, 修改表的操作

    1.外键: 用来建立两张表之间的关系 - 一对多 - 多对多 - 一对一 研究表与表之间的关系: 1.定义一张 员工部门表 id, name, gender, dep_name, dep_desc - ...

  3. mysql数据库导入导出 查询 修改表记录

    mysql数据导入导出: 导入: 把系统的文件的内容,保存到数据库的表里 导入数据的基本格式:mysql> load data infile "文件名" into table ...

  4. MySQL数据库基础(2)表结构管理

    目录 一.关系模型与数据表 二.MySQL数据类型 三.数据完整性约束 四.参照完整性约束 一.关系模型与数据表 概念 ①关系模型:是由若干个关系模式组成的集合,关系模式的实例称为关系,每个关系实际上 ...

  5. mysql大数据量下修改表结构的方法

    http://www.blogjava.net/anchor110/articles/361152.html

  6. 数据库遇到的问题——mysql在线修改表结构大数据表的风险与解决办法归纳

    互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需要我来考虑,虽然我们没 ...

  7. mysql在线修改表结构大数据表的风险与解决办法归纳

    整理这篇文章的缘由: 互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需 ...

  8. 查看mysql字符集及修改表结构--表字符集,字段字符集

    MySQL 乱码的根源是的 MySQL 字符集设置不当的问题,本文汇总了有关查看 MySQL 字符集的命令.包括查看 MySQL 数据库服务器字符集.查看 MySQL 数据库字符集,以及数据表和字段的 ...

  9. mysql 表关系 与 修改表结构

    目录 mysql 表关系 与 修改表结构 两张表关系 分析步骤 修改表结构 mysql 表关系 与 修改表结构 两张表关系 多对一 以员工和部门举例 多个员工对应一个部门 foreign key 永远 ...

随机推荐

  1. 3D可视化在化工领域的应用及案例分享

    2020年,中办.国办印发的<关于全面加强危险化学品安全生产工作的意见>中重点提出应加快"推进化工园区安全生产信息化.智能化平台建设,实现对园区内企业.重点场所.重大危险源.基础 ...

  2. 文件上传漏洞靶场分析 UPLOAD_LABS

    文件上传漏洞靶场(作者前言) 文件上传漏洞 产生原理 PASS 1) function checkFile() { var file = document.getElementsByName('upl ...

  3. CVPR2022 | 弱监督多标签分类中的损失问题

    前言 本文提出了一种新的弱监督多标签分类(WSML)方法,该方法拒绝或纠正大损失样本,以防止模型记忆有噪声的标签.由于没有繁重和复杂的组件,提出的方法在几个部分标签设置(包括Pascal VOC 20 ...

  4. MySQL 8.0 新特性梳理汇总

    一 历史版本发布回顾 从上图可以看出,基本遵循 5+3+3 模式 5---GA发布后,5年 就停止通用常规的更新了(功能不再更新了): 3---企业版的,+3年功能不再更新了: 3 ---完全停止更新 ...

  5. QT多线程的简单使用,主线程发一份数据,子线程收两份数据

    先看效果图,示例发送数据"Hello World" 主线程:0x16f54aeda20,另两个子线程分别是0x4f1baff690.0x4f1baff6a0 因为在子线程中加了20 ...

  6. python素描照片

    #!/usr/bin/python # -*- coding: utf-8 -*- from PIL import Image import numpy as np a = np.asarray(Im ...

  7. cut命令、case与select语句

    cut命令 常用参数: -c character 字符 -d delimiter 分隔符 -f field 域(列) --output-delimiter 输出分隔符 例: # echo 12345 ...

  8. namespace_std 杂题选讲

    CF1458C Latin Square 2021 EC Final C. Random Shuffle [THUPC2021] 混乱邪恶 [JOISC2022] 制作团子 3 2022 集训队互测 ...

  9. String长度限制?

    String我们在开发和学习中会经常用到,但对String类型的取值范围我们并不明确. String底层是char数组,并未标明长度限制.java中可以对数组指定长度,如果不指定就以实际元素来指定 p ...

  10. AMS1117降压电路

    AMS1117芯片为正向低压差稳压器,内部集成过热保护和限流电路,其固定输出版本电压可为1.5V.1.8V.2.5V.2.85V.3.0V.3.3V.5.0V,设计采用3.3V输出即ASM1117-3 ...