MySQL数据库线上如何修改表结构

一、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为原表名

  • 释放锁

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

改进:

MySQL数据库线上如何修改表结构

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

  • 好处是同步的过程不会影响原有的业务正常。

  • 缺点是过程中需要额外一倍的存储空间去存储这个新表,当rename完成之后,可以把老表删掉。

“MySQL数据库线上如何修改表结构”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

文章标题:MySQL数据库线上如何修改表结构,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/24074

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云的头像亿速云认证作者
上一篇 2022年9月8日 下午10:59
下一篇 2022年9月10日 下午11:37

相关推荐

  • windows KB4520010更新了哪些内容

    KB4520010主要更新方面: – 更新以提高使用 Internet Explorer 和 Microsoft Edge 时的安全性。 – 用于验证用户名和密码的更新。 – 用于存储和管理文件的更新。 KB4520010改进修补程序: 解决了安全公告 CVE-2…

    2022年9月1日
    30700
  • MySQL中的查询优化器怎么用

    对于一个SQL语句,查询优化器先看是不是能转换成JOIN,再将JOIN进行优化 优化分为:1. 条件优化,2.计算全表扫描成本,3. 找出所有能用到的索引,4. 针对每个索引计算不同的访问方式的成本,5. 选出成本最小的索引以及访问方式 一、开启查询优化器日志 — 开启set optimizer_…

    2022年9月15日
    52100
  • php unserialize反序列化漏洞分析

    题目如下: 漏洞解析: (上图代码第11行正则表达式应改为:’/O:d:/’) 题目考察对php反序列化函数的利用。在第10行 loadData() 函数中,我们发现了 unserialize 函数对传入的 $data 变量进行了反序列。在反序列化前,对变量内容进行了判断,先…

    2022年8月30日
    74400
  • WebView File域同源策略绕过漏洞实例分析

    基本知识Android架构 Kernel内核层 漏洞危害极大,通用性强 驱动由于多而杂,也可能存在不少漏洞 Libaries系统运行库层 系统中间件形式提供的运行库 包括libc、WebKit、SQLite等等 AndroidRunTime Dalvik虚拟机和内核库 FrameWork应用框架层 …

    2022年9月21日
    69800
  • windows KB4525245安装失败怎么解决

    根据情况可能不同,小编准备了五种解决方案 名列前茅种方案: 1.查看【windows update】、【app readiness】、【Cryptographic Services】、【Background Intelligent Transfer Service】、【Windows Install…

    2022年9月1日
    56900
  • Docker资源限制Cgroup怎么使用

    1.Cgroup简介 _cgroups,是一个非常强大的linux内核工具,他不仅可以限制被namespace隔离起来的资源, 还可以为资源设置权重、计算使用量、操控进程启停等等。所以cgroups (Control groups) 实现了对资源的配额和度量。 cgroups有四大功能: 资源限制:…

    2022年9月15日
    68400
  • C语言源码二次释放的危害是什么

    1、二次释放 二次释放简单理解就是对同一个指针指向的内存释放了两次,针对C语言源代码,对同一个指针进行两次 free() 操作,可能导致二次释放,本文3.1章节的缺陷代码就是对这类情况的描述。在C++语言中,浅拷贝操作不当是导致二次释放常见原因之一。如:调用一次赋值运算符或拷贝构造函数将会导致两个对…

    2022年9月19日
    69300
  • mysql如何查询名列前茅条数据

    在mysql中,可以使用SELECT语句配合LIMIT子句来查询名列前茅条数据,语法为“SELECT *|字段名列表 FROM 表名 LIMIT 0,1;”。LIMIT子句可以指定查询结果从哪条记录开始显示,显示多少条记录,语法“LIMIT 初始位置,记录数”,而名列前茅条记录的位置是0;因此想要显…

    2022年9月24日
    1.1K00
  • mysql与oracle有没有区别

    mysql与oracle有区别:1、Oracle是一个对象关系数据库管理系统(ORDBMS),而MySQL是一个关系数据库管理系统(RDBMS);2、Oracle是闭源的(收费),MySQL是开源的(免费);3、Oracle是大型数据库,而MySQL是中小型数据库;4、Oracle可设置用户权限、访…

    2022年9月22日
    3.3K00
  • jquery怎么获取屏幕宽高

    具体方法如下: 1.获取当前窗口可视区域宽度 $(window).width(); 2.获取当前窗口可视区域高度 $(window).height(); 3.获取当前窗口文档对象宽度 $(document).width(); 4.获取当前窗口文档的高度 $(document).height(); 相…

    2022年8月29日
    53700
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部