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

本文探讨了MySQL中的MDL元数据锁及其对并发操作的影响。MDL锁在表结构修改时自动添加,导致读写互斥,可能引发阻塞问题。为避免高峰期影响,建议在非业务时间进行表结构修改。提出了一种方案,涉及复制表结构、数据同步及rename操作,但可能导致服务短暂不可用。改进方案是通过数据订阅实时同步新表,减少服务中断时间,但需要额外存储空间。
摘要由CSDN通过智能技术生成

一、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完成之后,可以把老表删掉。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值