首先,用过数据库的小伙伴们(本文以 MySQL InnoDB 为例)都知道,MySQL 不止有增删改数据操作(DML),还有改表结构的操作(DDL),当新增加字段等修改表结构时,就需要进行 DDL 操作。可是,如果对一个存储了上百万甚至上千上万的数据表进行 DDL 操作,数据库是怎么做到的呢?会不会有一个很大的事务锁?会不会影响数据的插入和更新?今天就会聊聊这个问题,以及 PT-OSC、GH-OST 等技术,是如何高效的解决这个问题的。

Before MySQL 5.5

在 MySQL 5.5 版本及之前版本,DDL 操作主要有 copy table 和 inplace 两种方式。

1,Copy Table 方式

Copy Table 顾名思义,就是通过临时表拷贝的方式实现的。在 MySQL 5.5 版本及之前版本,修改表结构是表级锁,所以在整个 DDL 过程中表都是锁着不可写入的。这使得在修改时容易导致数据库 CPU、IO 等性能的消耗,以及主从同步的延迟。

上述过程,MySQL 自动完成转存数据,交换表名和删除旧表等操作,时间消耗最多的是在往临时表(Server 层)插入数据的过程,整个 DDL 过程中,表是不能执行 DML 的。

2,IN-Place 方式

在 MySQL 5.5 版本中,增加了 IN-Place 方式。所谓 IN-Place 方式,就是索引创建在原表上直接进行,不会 copy 整个表,只需要在原来的 idb 文件上,新建所需要的索引页,这比 Copy Table 节约极大的 IO 资源,且减少了 DDL 执行时长。

对比 Copy Table 和 IN-Place 两种方式,我们看下官网的内容(MySQL 5.5):

(引自:https://dev.mysql.com/doc/refman/5.5/en/alter-table.html)

以上是 MySQL 5.5 版本中的说明,而 MySQL 5.6 版本,则正式提出了 COPY 和 INPLACE 两种方式。

(引自:https://dev.mysql.com/doc/refman/5.6/en/alter-table.html)

3,Fast Index Creation(FIC)

Innodb 存储引擎从 1.0.x 版本开始,对添加索引操作引入了新特性 Fast Index Creation(FIC 特性)。FIC 就是添加或删除二级索引的时候,可以不用复制原表,而是在创建或删除二级索引时会对原表加上一个 S 锁(共享锁),允许其他会话进行读操作,但禁止写操作,根据当前表数据创建索引,新索引创建完成之后,解除 S 锁,允许写操作。

FIC 在创建索引时不需要拷贝整表数据,但只对二级索引有效,对主键索引无效,对于主键索引的创建和删除同样需要重建一个临时表。

对比 IN-Place 和 FIC,在网上查了一些资料,说“INPLACE 方式也称为 InnoDB fast index creation”,那两个应该不是一回事?我们看下官网的内容(MySQL 5.5):

(引自:https://dev.mysql.com/doc/refman/5.5/en/innodb-create-index-overview.html)

在 MySQL 5.5 的官方说明中,并没有明确说明 FIC 就是 INPLACE,并且此版本中的 FIC 只支持二级索引和辅助索引的增加和删除。而在 MySQL 5.6 官方说明中,则指出 Online DDL 特性基于 InnoDB FIC 构建。

(引自:https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl.html)

在 MySQL 8.0 的官方说明中,则指出了 FIC 是 Online DDL 的延伸和扩展。

(引自:https://dev.mysql.com/doc/refman/8.0/en/glossary.html)

所以,综上所述,“INPLACE 方式也称为 InnoDB fast index creation”这句话是对的,Online DDL 方式延伸了 Fast Index Creation,并逐渐扩展了 FIC 的范围。

Since MySQL 5.6

在 MySQL 5.6 版本,引入了 Online DDL,这个新特性解决了早期版本 MySQL 进行 DDL 操作时带来的锁表问题,Online DDL 执行的过程中依然保证可以读写,不影响数据库对外提供服务。

Online DDL

Alter table …. , ALGORITHM [=] {DEFAULT|INPLACE|COPY}, LOCK [=] { DEFAULT| NONE| SHARED| EXCLUSIVE }

ALGORITHM 子句指定执行 DDL 采用的方式,LOCK 子句描述持有锁类型来控制 DML 的并发。其中,某些 DDL 语句不支持 Online DDL 的采用 COPY 方式,支持的就采用 INPLACE 方式,因为 Online DDL 是对早期 INPLACE 方式的增强,所以 INPLACE 方式根据是否涉及记录格式的修改又分为:Rebuilds Table 和 No-Rebuilds Table,我们看下官方给出的内容(MySQL 5.7):

(引自:https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html)

基于 Online 对比 COPY 和 INPLACE,COPY 方法从表中的数据导出来的存放位置叫作 tmp_table,这是一个临时表,是在 server 层创建的。INPLACE 方法从表中重建出来的数据是放在 tmp_file 里的,这个临时文件是 InnoDB 在内部创建出来的,整个 DDL 过程都在 InnoDB 内部完成。

Online DDL 实现过程主要包括三个阶段:Initialization 阶段, Execution 阶段,Commit Table Definition 阶段。我们看下官方给出的内容(MySQL 8.0):

(引自:https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-performance.html)

我们详细描述下这三个过程的过程:

1,Initialization

  • 创建 frm 临时文件

  • 持有EXCLUSIVE_MDL锁,禁止读写

  • 根据 ALTER 操作,确定执行过程(COPY,Online-Rebuilds,Online-No-Rebuilds)

  • 更新数据字典的内存对象

  • 若是需要 Rebuilds,分配 row_log 对象记录增量

  • 若是需要 Rebuilds,新建 ibd 临时文件

2,Execution(如果仅修改 MetaData,则无此部操作)

  • 降低EXCLUSIVE-MDL锁,允许读写(COPY 仅允许读)

  • 记录执行期间产生的 DML 操作到 row_log(仅 Rebuilds 需要)

  • 扫描老表的聚集索引中每一条记录 record

  • 遍历新表的聚集索引和二级索引,逐一处理

  • 根据 record 构造对应的索引项

  • 将构造的索引项插入 sort_buffer 块中

  • 将 sort_buffer 块插入新的索引

  • 将 row_log 中的记录应用到新临时表,应用到最后一个 Block

3,Commit Table Definition

  • 升级到EXECLUSIVE-MDL锁,禁止读写

  • 重做 row_log 中最后一部分增量

  • 更新 InnoDB 的数据字典

  • 提交事务,写 InnoDB redo 日志

  • 修改统计信息

  • Rename 临时的 ibd 和 frm 文件

  • DDL 执行变更

我理解,Online DDL 中的 COPY 和 INPLACE 的区别在于有没有原地,COPY 会将数据从 InnoDB 存储层 copy 到 Server 层,而 INPLACE 不会;而 INPLACE 中的 Rebuilds 和 No-Rebuils 的区别在于,有没有重建表。

PT-Online-Schema-Change(PT-OSC)

全称 Percona Toolkit Online Schema Change,其中 Percona Toolkit 源自 Maatkit 和 Aspersa 工具,这两个工具是管理 MySQL 最有名的工具,但 Maatkit 已经不维护了,全部归并到 Percona Toolkit。Percona Toolkit 是一组高级的命令行工具,用来管理 MySQL 和系统任务。

PT-OSC(pt-online-schema-change)工具特点与优势是支持并发 DML 操作。

GitHub’s Online Schema Transformer(GH-OST)

GH-OST 是 GitHub 的在线表定义转换器,与 PT-OSC 的最大区别,在于 GH-OOST 的无触发器设计。

至此,我们对比下 Online DDL、PT-OSC 和 GH-OST 的优缺点:

(引自:吴夏《在线DDL原理、对比分析和实践》)

总结

传统的 DDL,多数的 ALTER TABLE 操作是通过创建一个满足需求的新表,之后拷贝数据到新表,在用新表替换老表,整个过程会加锁,不支持并发 DML。在 MySQL 5.5 版本中,以 InnoDB Plugin 方式,优化了新增和删除索引的操作,避免了这种数据 copy 的开销,出现了 FIC。在 MySQL 5.6 开始增强了对各种 ALTER TABLE 操作支持,避免数据 copy 的开销,同时允许在 DDL 进行中,并发执行 DML 操作。在 MySQL 5.7 实现了 ALTER TABLE RENAME INDEX 操作,即支持在线的索引重命名,这种特性的综合,即 ONLINE DDL。PT-OST 通过改造原生 DDL 的方式,实现不锁表的在线修改表结构。

Reference

https://segmentfault.com/a/1190000014924677

https://www.cnblogs.com/abclife/p/7505064.html

http://seanlook.com/2016/05/24/mysql-online-ddl-concept/

https://cloud.tencent.com/developer/article/1005177

https://www.cnblogs.com/xinysu/p/6732646.html

http://m.mamicode.com/info-detail-2311611.html

http://www.debugger.wiki/article/html/1550203202837500

https://www.cnblogs.com/TeyGao/p/9089997.html

https://www.w3xue.com/exp/article/20192/21034.html

作者公众号:

浅谈 DDL 技术解密相关推荐

  1. 浅谈虚拟化技术下的云安全如何处置

    浅谈虚拟化技术下的云安全如何处置 近年来,云计算是目前非常热门的一个研究领域,其实它并不是一种全新的技术,而是许多技术的融合体,包括分布式计算.动态和拓展等各种各样的技术算法,而虚拟化技术是云计算里最 ...

  2. 浅谈.NET技术公司的实习生培养

    浅谈.NET技术公司的实习生培养 背景 近几年.NET开发者市场的越发不景气,一毕业就选择.NET技术的开发者更是少之又少.一方面是公司效益的日益提高,一方面却是招聘优秀人才的速度总是赶不上公司发展的 ...

  3. 浅谈Hybrid技术的设计与实现【转】

    https://www.cnblogs.com/yexiaochai/p/4921635.html 前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术 ...

  4. 浅谈Hybrid技术的设计与实现第二弹

    前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术的设计与实现第三弹--落地篇 接上文:浅谈Hybrid技术的设计与实现(阅读本文前,建议阅读这个先) ...

  5. 智能车浅谈——抗干扰技术硬件篇

    文章目录 前言 干扰 什么是干扰 干扰窜入的主要途径 干扰的分类 硬件抗干扰技术 控制系统的电源保护技术 输入/输出传输线的抗干扰措施 I/O接口的抗干扰措施 接地技术 总结 智能车系列文章汇总 前言 ...

  6. 智能车浅谈——抗干扰技术软件篇

    文章目录 软件抗干扰技术 数字信号的抗干扰措施 数字输入信号软件抗干扰措施 数字输出信号软件抗干扰措施 数字滤波 算术平均值滤波 中值滤波 滑动平均滤波 归一化 差比和 CPU及程序的抗干扰措施 复位 ...

  7. 计算机辅助设计对提升产品质量,浅谈CAD技术与计算机辅助设计的应用

    浅谈CAD技术与计算机辅助设计的应用 来源:用户上传 作者: 杨思宇 [摘 要]随着社会经济的不断发展与进步,各领域的技术也不断的进行着革新.本文以计算机辅助设计当中的开发出的成组技术为主,对成组技术 ...

  8. 计算机技术在现代地球科学中的重要性,浅谈GIS技术在地球科学中的应用.doc

    浅谈GIS技术在地球科学中的应用.doc 浅谈GIS技术在地球科学中的应用 中图分类号:P9 文献标识码:A 文章编号:1007-0745(2014)02-0181-01 摘要:地理信息系统是指带各种 ...

  9. 遥感在计算机领域的应用,浅谈遥感技术在测绘领域发展应用.doc

    浅谈遥感技术在测绘领域发展应用 浅谈遥感技术在测绘领域发展应用 摘要: 随着整个科学技术的飞速发展,遥感技术的发展是计算机.空间.通信.电子学等新兴技术和传统的物理.地学.数学.生物等科学的交叉.渗透 ...

最新文章

  1. 浅谈Java内存泄漏问题
  2. 系统测试和集成测试的区别
  3. Leetcode 刷题笔记
  4. spring核心功能包中已经包含了cglib功能
  5. 一图看懂py2/py3编码
  6. go语言 doc转换html,go语言使用wkhtmltopdf工具将html转成pdf
  7. 【JEECG技术博文】JEECG图表配置说明
  8. ie com接口 php_PHP webservie连接.net接口
  9. Unity3D基础35:五彩砖块
  10. 易语言自定义数据类型转c,转换JSON结构为易语言代码自定义数据类型
  11. 自定义Dialog去除白色背景 + Dialog其他用法
  12. 区块链从入门到精通 - 区块链培训
  13. HMMer在Windows环境下的安装
  14. 清除WAS的僵死进程
  15. New Bing已经出来了,怎么防止Bing跳转到国内版(cn.bing.com)?
  16. 经常玩电脑正确的坐姿_电脑族玩游戏正确坐姿 7要点坐不伤身
  17. 最新sogou搜狗搜索 机智操作绕过反爬验证码!
  18. 2020年感冒人群大幅度减少,不感冒意味着身体变好?
  19. PaaS平台如何实现简化应用开发和部署
  20. 富头像上传编辑器(flash头像上传插件)

热门文章

  1. 《R语言数据分析》作业答案
  2. 一种改进的天鹰优化算法和非洲秃鹫混合优化算法(Matlab代码实现)
  3. 【软件测试】如何梳理你测试的业务
  4. 电脑win10无法自动修复此计算机,如何解决Win10自动修复无法修复你的电脑?
  5. SSH git初次克隆代码问题报错 fatal: unable to update url base from redirection:
  6. 儿童交通安全教育宣传手抄报模板
  7. php mysql 开发成本_Java凭什么比PHP+MYSQL开发的B2B软件值钱
  8. 23种设计模式-依赖倒转原则
  9. notepad++查看二进制.class文件——HexEditor插件(64/32位)安装教程
  10. IO缓冲(buffer)和高速缓存(cache)