Mysql Online DDL的使用详解

 更新时间:2021年05月20日 11:32:44   作者:xmebcc  
在日常DBA运维过程中,对表结构进行变更算是个普遍的需求了。如果操作的对象是个热表、大表,难免心里一怵,这些DDL操作是否可以直接执行,哪些会影响线上读写,哪些会影响主从,甚至导致服务器压力骤升,本文做了梳理,希望对大家有所帮助。

正文

Online DDL在MySQL 5.6才开始支持的,在5.5及之前版本,使用alter table/create index等命令进行表结构修改操作均会锁表,这在生产环境上明显是不可接受的。

在MySQL 5.7,Online DDL在性能和稳定性上不断得到优化,性能有显著优势,且对业务负载影响小,停写时间可控,相对pt-osc/gh-ost来说,无需安装第三方依赖包,同时支持Inplace算法的Online DDL,由于无需拷表,所需磁盘空间也更小。

先来看一个常见的DDL语句:

ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;

其中,LOCK描述了DDL期间运行的并发程度,ALGORITHM描述了DDL的实现方式

LOCK参数

  1. LOCK=NONE:允许并发的查询和DML操作
  2. LOCK=SHARED:允许并发的查询,但阻塞DML操作
  3. LOCK=DEFAULT: 由系统决定,允许尽可能多的并发性(并发查询、DML或两者)。如果省略LOCK子句相当于指定LOCK=DEFAULT
  4. LOCK=EXCLUSIVE:阻塞并发查询和DML操作。

ALGORITHM参数

  1. ALGORITHM=COPY:采用拷表方式进行表变更,与pt-osc/gh-ost类似;
  2. ALGORITHM=INPLACE:仅需要进行引擎层数据改动,不涉及Server层;

COPY TABLE流程

  1. 首先建立临时表,表结构为ALTAR TABLE更改后的结构
  2. 将原表中数据导入到临时表(server层创建临时表,会有显示的IBD文件)
  3. 删除原表
  4. 将临时表rename为原来的表名

同时这一过程中,为了保持数据的一致性,中间复制数据时(Copy Table)全程锁表只读,如果有写请求进来将无法提供服务,将导致连接数爆张。

IN-PLACE流程

  1. 建立一个临时文件,扫描原表主键的所有数据页
  2. 用数据页中原表记录生成B+树,存储到临时文件中(innodb_temp_data_file_path临时表空间下创建临时文件)
  3. 生成临时文件的过程中,将所有对原表的操作记在一个日志文件(rowlog)中
  4. 临时文件生成后,将日志文件中的操作应用到临时文件,得到一个辑数据上与原表相同
  5. 数据文件(日志文件记录和重放操作)
  6. 用临时文件替换原表数据文件

这一过程中,alter 语句在启动的时候获取MDL写锁,但是这个写锁在真正拷贝数据之前就退化成读锁,也就是说在最耗时的copy数据到临时文件的过程中,原表是可以进行dml操作的,仅仅会在最后的新旧表切换阶段加锁,这个rename的时间就非常快了。

允许并发DML的DDL操作

  • 创建/新增二级索引
  • 重命名二级索引
  • 删除二级索引
  • 改变索引类型(USING {BTREE | HASH})
  • 添加主键(expensive cost)
  • 删除主键并增加另一个(expensive cost)(ALTER TABLE tbl_name DROP PRIMARY KEY, ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;)
  • 新增列 (expensive cost)
  • 删除列 (expensive cost)
  • 重命名列
  • 列重新排序 (expensive cost)
  • 改变列默认值
  • 删除列默认值
  • 改变列自增值
  • 设置列属性null/not null (expensive cost)
  • 修改枚举或集合列的定义
  • Change ROW_FORMAT
  • Change key block size

标记为expensive cost的操作虽然允许OnlineDDL,但本身对服务器IO,CPU都会造成较高负担,同时会导致复制阻塞,造成另一种形式的从库复制延迟,所以如果是大表,建议业务低峰期执行

不允许并发DML的DDL操作

  • 添加全文索引
  • 添加空间索引
  • 删除主键
  • 改变列数据类型
  • 添加自增列(新增列->变为自增列)
  • 变更表字符集
  • 修改数据类型长度
    • 特例:varchar字符长度从10变更到小于255 采用inplace方式不会锁表;从255变更到10会锁表;

以上就是Mysql Online DDL的使用详解的详细内容,更多关于Mysql Online DDL的使用的资料请关注脚本之家其它相关文章!

相关文章

  • 如何优雅安全的备份MySQL数据

    如何优雅安全的备份MySQL数据

    这篇文章主要介绍了如何优雅安全的备份MySQL数据的相关资料,需要的朋友可以参考下
    2022-10-10
  • MySQL如何优化索引

    MySQL如何优化索引

    这篇文章主要介绍了MySQL如何优化索引,帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2020-12-12
  • Mysql允许外网访问设置步骤

    Mysql允许外网访问设置步骤

    本文给大家分享Mysql允许外网访问设置步骤,通过简单的五步操作就可以实现mysql允许外围访问功能,非常不错,需要的朋友参考下吧
    2016-10-10
  • Mysql存储二进制对象数据问题

    Mysql存储二进制对象数据问题

    这篇文章主要介绍了Mysql存储二进制对象数据问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • MySQL慢查询日志的作用和开启

    MySQL慢查询日志的作用和开启

    这篇文章主要给大家介绍了关于MySQL慢查询日志的作用和开启的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • windows下MySQL5.6版本安装及配置过程附有截图和详细说明

    windows下MySQL5.6版本安装及配置过程附有截图和详细说明

    这篇文章主要介绍了windows下MySQL5.6版本安装及配置过程附有截图和详细说明,需要的朋友可以参考下
    2013-06-06
  • MySQL的数据类型和建库策略分析详解

    MySQL的数据类型和建库策略分析详解

    无论是在小得可怜的免费数据库空间或是大型电子商务网站,合理的设计表结构、充分利用空间是十分必要的。这就要求我们对数据库系统的常用数据类型有充分的认识。下面我就将我的一点心得写出来跟大家分享。
    2008-04-04
  • Mysql报错too many connections的原因及解决方案

    Mysql报错too many connections的原因及解决方案

    这篇文章主要给大家介绍了关于Mysql报错too many connections原因及解决方案,文中通过实例代码以及图文介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • 详解MySQL中varchar和int隐式转换的注意事项

    详解MySQL中varchar和int隐式转换的注意事项

    这篇文章主要为大家详细介绍了MySQL中varchar和int隐式转换的注意事项,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-12-12
  • Mysql查询正在执行的事务以及等待锁的操作方式

    Mysql查询正在执行的事务以及等待锁的操作方式

    今天小编就为大家分享一篇关于Mysql查询正在执行的事务以及等待锁的操作方式,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论