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为原表名
- 释放锁
以上方案的问题是,数据量很大的时候,数据都导入需要时间,这个过程中,服务是不可访问的。
改进:

新建一张表 A_new,其比原表多了几个字段,通过数据订阅的方式订阅原表A,把线上的表A中的数据同步到这个新建的表A_new中,这个过程会一直持续,并且这个过程中表A是可以增删改查的,总有一个时刻,这两张表的数据是完全同步的,数据上是没有任何差异的,这个时候把原表表名A给修改掉,把新表A_new修改为原表A,这个操作是一个短暂操作,可以瞬间完成,不会有很大影响。
优缺点:
- 好处是同步的过程不会影响原有的业务正常。
- 缺点是过程中需要额外一倍的存储空间去存储这个新表,当rename完成之后,可以把老表删掉。
MySQL数据库如何线上修改表结构的更多相关文章
- MySQL 分区表 partition线上修改分区字段,后续进一步学习partition (1)
公司线上在用partition,有一个表的分区字段错了,需要重建,结果发现没有办法像修改主键字段或者修改索引字段那样直接一条sql搞定.而是需要建临时表,有down time,所以去仔细看了文档,研究 ...
- MySQL数据库 外键,级联, 修改表的操作
1.外键: 用来建立两张表之间的关系 - 一对多 - 多对多 - 一对一 研究表与表之间的关系: 1.定义一张 员工部门表 id, name, gender, dep_name, dep_desc - ...
- mysql数据库导入导出 查询 修改表记录
mysql数据导入导出: 导入: 把系统的文件的内容,保存到数据库的表里 导入数据的基本格式:mysql> load data infile "文件名" into table ...
- MySQL数据库基础(2)表结构管理
目录 一.关系模型与数据表 二.MySQL数据类型 三.数据完整性约束 四.参照完整性约束 一.关系模型与数据表 概念 ①关系模型:是由若干个关系模式组成的集合,关系模式的实例称为关系,每个关系实际上 ...
- mysql大数据量下修改表结构的方法
http://www.blogjava.net/anchor110/articles/361152.html
- 数据库遇到的问题——mysql在线修改表结构大数据表的风险与解决办法归纳
互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需要我来考虑,虽然我们没 ...
- mysql在线修改表结构大数据表的风险与解决办法归纳
整理这篇文章的缘由: 互联网应用会频繁加功能,修改需求.那么表结构也会经常修改,加字段,加索引.在线直接在生产环境的表中修改表结构,对用户使用网站是有影响. 以前我一直为这个问题头痛.当然那个时候不需 ...
- 查看mysql字符集及修改表结构--表字符集,字段字符集
MySQL 乱码的根源是的 MySQL 字符集设置不当的问题,本文汇总了有关查看 MySQL 字符集的命令.包括查看 MySQL 数据库服务器字符集.查看 MySQL 数据库字符集,以及数据表和字段的 ...
- mysql 表关系 与 修改表结构
目录 mysql 表关系 与 修改表结构 两张表关系 分析步骤 修改表结构 mysql 表关系 与 修改表结构 两张表关系 多对一 以员工和部门举例 多个员工对应一个部门 foreign key 永远 ...
随机推荐
- salt stack安装与使用
SaltStack除了传统的C/S架构外,其实还有Masterless架构,如果采用Masterless架构,我不需要单独安装一台SaltStack Master机器,只需要在每台机器上安装Minio ...
- 简单ELK配置实现生产级别的日志采集和查询实践
概述 生产问题 集群规模如何规划? 集群中节点角色如何规划? 集群之脑裂问题如何避免? 索引分片如何规划? 分片副本如何规划? 集群规划 准备条件 先估算当前系统的数据量和数据增长趋势情况. 现有服务 ...
- Linux操作系统(7):rpm包管理和yum软件包在线管理
一.rpm 包的管理 介绍:一种用于互联网下载包的打包及安装工具,它包含在某些 Linux 分发版中.它生成具有.RPM 扩展名的文件.RPM 是 RedHat Package Manager(Red ...
- manjaro 安装后的基本配置
第一步:设置官方镜像源 sudo pacman-mirrors -i -c China -m rank # 输入以上命令后会有弹出框,选择一个国内镜像(推荐 https://mirrors.ustc. ...
- flashplayer下载
现在网上不好找,折磨了我好久.这有一个方法,或许能帮到你. 下载地址:https://gitee.com/urain39/adobe-flash_player_sa 官网已经停止更新维护了,连Debu ...
- Java双重校验单例模式详解
单例模式双重检测java实现: public class Singleton { private volatile static Singleton instance = null; //#1 pub ...
- element多重校验报please transfer a valid prop path to form item
- 序列化和返序列化的概述和对象的序列化流ObjectOutputStream
序列化和返序列化的概述 对象的序列化流ObjectOutputStream Person类: package com.yang.Test.ObjectStreamStudy; import java. ...
- 2536-springsecurity系列--关于session管理1
版本信息 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring ...
- 使用Python3.7结合Redisearch代替ElasticSearch实现的全文检索功能服务
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_105 "检索"是很多产品中无法绕开的一个功能模块,当数据量小的时候可以使用模糊查询等操作凑合一下,但是当面临海 ...