点击上方"蓝字"

关注我们,享更多干货!

DDL变更是MySQL运维当中,避免不了的日常工作,也是影响比较大的操作。为了减少风险,开源社区提供了gh-ost、pt-online-schema-change这样便利的工具,解决了一些堵塞问题,但还是存在很多不确定的因数。

比如当数据量较大的表需要表更时:

  • 创建触发器过程中穷住了

  • binlog同步发生了延迟,导致DDL无法完成

  • 执行过程中,内存占满、CPU 100% 、IO等待
    最终导致阻塞读写请求(DML操作阻塞),影响系统的可用性。

所以DDL操作,要考虑这些因素,避开高峰期,操作评估,预备手段需要准备好。

除了上述方式,官方的Online DDL也是一种很好的方式。Online DDL是在MySQL 5.6版本后加入的特性,用于支持DDL执行期间DML语句的并行操作,提高数据库的吞吐量。目前迭代到的8.0,了解一下都有那些变化。

1

   Online DDL

MySQL在线DDL特性提供了即时支持instant 、copy方式,还有原表in-place方式。有些过程中也允许并发DML。

关键点:

就是ALGORITHM,LOCK 这个指标。

ALTER TABLE tbl_name ,
alter_option: {...},
ALGORITHM [=] {DEFAULT | INSTANT | INPLACE | COPY}
LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}

为了避免在执行ALTER TABLE操作时表可读或不可写,可以在ALTER TABLE语句中指定一个子句,如果请求是并发级别且不可用,则操作立即停止。

构建方式:
  • COPY:对原始表的一个副本执行操作,将表数据从原始表逐行复制到新表。不允许并发DML。

    通过临时表拷贝的方式实现的。新建一个带有新结构的临时表,将原表数据全部拷贝到临时表,然后Rename,完成创建操作。可能内存、IO、CPU、硬盘空间使用上升。

  • INPLACE:操作避免复制表数据。在操作的准备和执行阶段,可以简单地使用表上的独占元数据锁,通常支持并发DML。所谓INPLACE,也就是在原表上直接进行,不会拷贝临时表。与COPY操作相比,向缓冲池中读取的数据更少,这减少了从内存中清除频繁访问的数据。

  • INSTANT:操作仅修改数据字典中的元数据。在准备和执行期间,表上没有独占元数据锁,并且表数据不受影响,这使得操作是瞬时的。允许并发DML。(MySQL8.0.12开始)
    上述图中符号就是即时操作。

备注:

可以理解COPY方式是把数据抽出来,再灌入进去,类似于Server层的操作。可以支持所有引擎。

INPLACE方式是在InnoDB引擎层完成,比如会多个frm 、ibd方式。底层InnoDB引擎在协助处理这个过程。

INSTANT就是元数据的更改。

锁级别:
  • LOCK=NONE:允许并发查询和DML(允许读和写) 。

  • LOCK=SHARED:允许并发查询,但阻塞DML (允许读)

  • LOCK=EXCLUSIVE:阻塞并发查询和DML (独占元数据锁),尽可能短的时间内完成DDL操作。特别是服务器空闲时候,可以使用这个子句。

2

   Online DDL的实现过程

在线DDL操作可以被看作有三个阶段:

阶段1: Initialization初始化

在初始化阶段,服务器将考虑存储引擎功能、语句中指定的操作以及用户指定的ALGORITHM和LOCK选项,确定操作期间允许多少并发性。在此阶段,使用一个共享的可升级元数据锁来保护当前表定义。

阶段2:Execution执行

在这个阶段,语句是准备和执行的。元数据锁是否升级为排他锁取决于初始化阶段评估的因素。如果需要独占元数据锁,则只在语句准备期间短暂地使用它。

阶段3:Commit Table Definition 提交表定义

在提交表定义阶段,元数据锁升级为排他锁,以排除旧表定义并提交新表定义。一旦授予,独占元数据锁的持续时间就会很短。

3

   Online DDL要求

与基本存放临时日志文件的空间有关系:

  • 当在线DDL操作创建索引或修改表时,一个临时日志文件记录并发的DML。临时日志文件根据innodb_sort_buffer_size的值扩展到innodb_online_alter_log_max_size指定的最大值。如果临时日志文件的大小超过限制,则在线DDL操作失败(出现DB_ONLINE_LOG_TOO_BIG错误),未提交的并发DML操作将回滚。较大的innodb_online_alter_log_max_size设置允许在在线DDL操作期间使用更多的DML,但也会延长锁定表以应用日志DML时DDL操作结束的时间。

  • 用于临时排序文件的空间

    建表的在线DDL操作在创建索引时将临时排序文件写入MySQL临时目录(Unix上的$TMPDIR, Windows上的%TEMP%,或由——TMPDIR指定的目录)。在包含原始表的目录中不会创建临时排序文件。每个临时排序文件都足够大,可以容纳一列数据,当将每个排序文件的数据合并到最终的表或索引中时,每个排序文件都会被删除。涉及临时排序文件的操作可能需要的临时空间等于表中的数据量加上索引。如果在线DDL操作使用了数据目录所在文件系统上的所有可用磁盘空间,则报告一个错误。

    如果MySQL临时目录不够大,不能保存排序文件,那么将tmpdir设置为另一个目录。或者,使用innodb_tmpdir为在线DDL操作定义一个单独的临时目录。

  • 中间表文件的空间

    一些重建表的在线DDL操作在与原始表相同的目录中创建一个临时中间表文件。中间表文件可能需要与原始表大小相等的空间。中间表文件名以#sql-ib前缀开始,仅在线DDL操作期间短暂出现。innodb_tmpdir选项不适用于中间表文件。

4

   失败条件

  • ALGORITHM子句指定了与特定类型的DDL操作或存储引擎不兼容的算法。

  • LOCK子句指定与特定类型的DDL操作不兼容的低级别锁定(SHARED或NONE)。

  • 在等待表上的排他锁时发生超时,这可能在DDL操作的初始和最终阶段短暂需要。

  • tmpdir或innodb_tmpdir文件系统的磁盘空间耗尽。

  • 并发的DML修改了很多表,以至于临时在线日志的大小超过了innodb_online_alter_log_max_size配置选项的值。这种情况会导致DB_ONLINE_LOG_TOO_BIG错误。

  • 并发DML对原始表定义允许的表进行更改,但新表定义不允许。当MySQL尝试应用并发DML语句的所有更改时,这个操作只会在最后失败。例如,在创建唯一索引时,可以在列中插入重复值,或者在列上创建主键索引时,可以在列中插入NULL值。并发DML所做的更改优先,并且ALTER TABLE操作被有效回滚。

5

  执行进度监控

独占元数据锁(exclusive):在线DDL操作可能必须等待持有表上元数据锁的并发事务提交或回滚。通过show processlist通常看到穷住的情况如下

State: Waiting for table metadata lock
  • 元数据锁信息还通过performance_schema库查看

mysql> SELECT  * FROM  performance_schema.metadata_locks\G;
  • 使用性能模式更改表监视:

mysql> UPDATE performance_schema.setup_instrumentsSET ENABLED = 'YES'WHERE NAME LIKE 'stage/innodb/alter%';

再通过performance_schema.events_stages_current表来检查ALTER TABLE操作的进度。显示的阶段事件根据当前正在进行的ALTER TABLE阶段的不同而不同。

mysql>SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_current;
+------------------------------------------------------+----------------+----------------+| EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED |
+------------------------------------------------------+----------------+----------------+| stage/innodb/alter table (read PK and internal sort) | 280 | 1245 |
+------------------------------------------------------+----------------+----------------+1 row in set (0.01 sec)

备注:

1)WORK_COMPLETED列显示已完成的工作。

2)work_estimate列提供了对剩余工作的估计。

6

  总结

在线DDL变更可能带来的风险,如果操作失败,回滚在线DDL操作的代价可能很高。

  • 修改大表结构执行时间往往不能预估,一般时间较长,可能带来的风险有:修改表结构是表级锁,影响DML写入操作。

  • 修改大表耗时较长,中途写入失败需要进行回滚,回滚这段时间也是不可写入。

  • 修改大表结构容易导致数据库CPU、IO性能损耗,降低MySQL服务性能。

  • 修改大表结构容易造成主从延迟加大,影响业务读取。

需要DBA介入评估。

其实最好的方式在从库上修改表结构,将结构变更了的从库设置为主库。


墨天轮原文链接:https://www.modb.pro/db/85208?sjhy(复制到浏览器或者点击“阅读原文”立即查看)

关于作者

崔虎龙,云和恩墨MySQL技术顾问,长期服务于金融、游戏、物流等行业的数据中心,设计数据存储架构,并熟悉数据中心运营管理的流程及规范,自动化运维等。擅长MySQL、Redis、MongoDB数据库高可用设计和运维故障处理、备份恢复、升级迁移、性能优化。自学通过了MySQL OCP 5.6和MySQL OCP 5.7认证。2年多开发经验,10年数据库运维工作经验,其中专职做MySQL工作8年;曾经担任过项目经理、数据库经理、数据仓库架构师、MySQL技术专家、DBA等职务;涉及行业:金融(银行、理财)、物流、游戏、医疗、重工业等。

END

由中国DBA联盟和墨天轮主办的 2021数据技术嘉年华 将于11月19日-20日在北京丽都皇冠假日酒店盛大召开。

大会门票限时0元领取

    扫描下方的二维码即可!

MySQL在其版本迭代后Online DDL功能发生了哪些变化?相关推荐

  1. MySQL 8.0版本安装后,安装目录下找不到my.ini文件

    安装路径是: 找了半天都没有找到,肿么办? 最后在C盘下找到了: C:\ProgramData\MySQL\MySQL Server 8.0

  2. 【转载】程序员毕业后的第二年发生了哪些变化?

    https://blog.csdn.net/csdnsevenn 作者 拭心 原标题 <毕业两年总结> 如需转载,请联系原作者授权. 去年七月写了<毕业一年总结>,一转眼就又是 ...

  3. Paintinglite迎来v2.1.2优化版本迭代,引入Pod安装

    Paintinglite 下载地址 Github Paintinglite. v2.1.2版本,全新设计模式,全新管理数据库 版本迭代 Paintinglite版本更新 v1.1.0 版本更新概要 优 ...

  4. 版本迭代规划的几大关键步骤

    产品经理对于如何做版本迭代规划,有时总会产生无力感,要么是计划难以确定下来,要么是制定好的计划无法执行下去,这个问题的原因很复杂.在项目初期,我们缺少对产品的全局概念和整体把握,内部意见很难统一:再者 ...

  5. mysql 删除数据后myd_Windows下的MySQL删除data文件夹后……

    MySQL删除data文件夹后,怎么都无法启动了,出现错误: 150106 9:28:43 [Note] Plugin 'FEDERATED' is disabled. wampmysqld: Tab ...

  6. zabbix企业应用之监控mysql 5.6版本

    最近很多人都问我如何为什么使用我之前博客的模板不能监控了,经过沟通发现对方的mysql版本是5.6,在进行命令行查看数据的实话,使用mysql -uxxx -pxxx -Pxxx的时候,会如下报错 W ...

  7. Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本)...

    Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本) Hive 安装依赖 Hadoop 的集群,它是运行在 Hadoop 的基础上. 所以在安装 Hive 之 ...

  8. docker yum php mysql_Centos下 使用Docker, 配置PHP+Nginx+Mysql(多PHP版本)

    Centos下 使用Docker, 配置PHP+Nginx+Mysql(多PHP版本) 2年前 阅读 6556 评论 0 喜欢 0 ### 一.先安装Dokcer: 1.安装一些必要的系统工具: `s ...

  9. MySQL 5.6版本GTID复制异常处理一例

    昨天处理了一个MySQL 5.6版本下开启GTID模式复制异常案例,MASTER上的任何操作都无法在SLAVE上应用,SLAVE的RELAY LOG里有记录,但SLAVE的BINLOG却找不到蛛丝马迹 ...

最新文章

  1. python面试-Python面试技巧合集(建议收藏)
  2. Spring Enable批注–编写自定义的Enable批注
  3. Java集合框架之三:HashMap源码解析
  4. c++函数不允许递归_面试算法题:不会递归函数被面试官刷了下来!
  5. 20190804:有效的括号(误删补发)
  6. python xpath循环_Python爬虫 爬取北京二手房数据
  7. Python:如何安装与使用 pip
  8. PCL之ubuntu安装CloudCompare
  9. 使用IOCP需要注意的一些问题~~(不断补充)
  10. dict( )、zip( )函数——python小练
  11. windows 进程通信(使用DDE)
  12. 最好的开源网络入侵检测工具
  13. 串行通信——异步串行通信
  14. 用户场景分析的四要素是什么?
  15. Elementui删除表格最后一页全部数据后跳到前一页的骚气写法
  16. JAVA知识体系之分布式篇(七)——Redis
  17. 衡水二中2021清华北大高考成绩查询,前进中的衡水二中,2019清华北大106人,成功绝非偶然...
  18. 驱动开发:内核MDL读写进程内存
  19. python round函数用法
  20. html怎么给图片加个叉,html 中的本地图片显示红叉.路径没問題

热门文章

  1. python运行方法_对python中执行DOS命令的3种方法总结
  2. SSM 整合开发初见面
  3. 南亚三大半岛_南亚最大的维基百科聚会开始
  4. 每日面试之Java集合
  5. Bootstrap 高亮某个菜单项
  6. es6 Node加载
  7. 传感器绕着世界坐标系旋转产生的疑惑
  8. 定义mysql日志_请教:如何查看mysql数据定义操作的日志
  9. php中strtotime的意思,PHP中strtotime
  10. 计算机怎么把硬盘分成几个,如何把电脑的一个盘的容量分给另外一个盘