MySQL数据的ONLINE DDL操作测试

旧城冷巷雨未停 提交于 2021-01-24 20:53:46

最近在研究如何给MySQL数据库的大表在线添加索引,查询了下资料,MySQL提供了online ddl功能,可以不锁表的执行DDL操作,网络上有些文章有讲解,但是都没有做基准测试。今天正好有空,就做个测试看看online DDL的实际效果。

online DDL简介

online DDL功能为表结构的更改和并发DML提供支持。此功能的优点包括:

  • 几乎不影响线上DML语句的效率。
  • 使用LOCK子句在DDL操作期间调整性能和并发之间的平衡。
  • 与表复制方法相比,磁盘空间使用量和I / O开销更少。

参数介绍[引用1]:

ALGORITHM:

  • DEFAULT:默认方式,在 MySQL 8.0中,如果未显示指定 ALGORITHM,那么会优先选择 INSTANT 算法,如果不行再使用 INPLACE 算法,如果不支持 INPLACE 算法则使用 COPY 的方式完成。(8.0以上版本)
  • INSTANT:添加列时立即返回。但是不能是虚拟列。这个原理很简单,对于新建一列,表所有原有数据并不是立刻发生变化,只是在表字典里面记录下这个列和默认值,对于默认的 Dynamic 行格式(其实就是 Compressed 的变种),如果更新了这一列则原有数据标记为删除在末尾追加更新后的记录。这样做就是没有提前预留出列空间,之后更新可能经常会发生行记录空间变动。但是对于大多数业务,都是最近的时间的记录才会修改,所以问题不大。(8.0以上版本)
  • INPLACE:在原表上直接进行修改,不会拷贝临时表,可以逐条记录修改,不会产生大量的 undolog 以及 redolog,不会占用很多 buffer。可以避免重建表带来的IO和CPU消耗,保证期间依然良好的性能和并发。
  • COPY:拷贝到临时新表上进行修改。由于记录拷贝,会产生大量的 undolog 以及 redolog,并占用很多 buffer,对业务性能有影响。

LOCK:

  • DEFAULT:和 ALGORITHM 的 DEFAULT 类似(8.0以上版本)
  • NONE:无锁,允许并发读取和更新表
  • SHARED:共享锁,允许读取不允许更新
  • EXCLUSIVE:不允许读取和更新

官方文档

https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes

基础配置

服务器配置:

thinkPad笔记本

CPU:i3五代 2.00GHz 4核

内存:8G

MySQL:5.6

数据准备

单表20个字段,ID主键索引之外添加三个非主键索引且其中一个为唯一索引。

起始准备数据1400W条,数据总量约600M。

DDL

为数据表添加一列默认为null的varchar类型的字段,长度为255。

  • ALGORITHM=INPLACE
  • LOCK=NONE

测试过程即结果分析

仅执行online DDL

不对表进行CURD的任何操作,仅执行online DDL,最终的执行结果为531.4s。

执行读取操作的同时执行online DDL

  • 开启10个线程,每个线程以10次/秒的速率访问数据库,通过ID作为查询条件做select操作。
  • 同时执行online DDL语句。
  • 在执行online DDL前,数据库读取操作每个耗时在0.01秒上下。
  • 执行online DDL过程中,开始阶段数据库读取操作每个耗时增加到0.1秒上下,此过程持续约30秒时间,随后稳定在0.01秒上下,与未执行online DDL之前一致。

执行读取和修改操作的同时执行online DDL

  • 开启20个线程,其中10个线程中的每个线程以10次/秒的速率访问数据库,通过ID作为查询条件做select操作;另外10个线程中的每个线程以10次/秒的速率先通过ID查询数据,再以ID作为条件执行update操作。
  • 同时执行online DDL语句。
  • 在执行online DDL前,数据库读取操作每个耗时在0.01秒上下,读取加修改操作每个耗时在0.03秒上下。
  • 执行online DDL过程中,开始阶段读取操作耗时增长到0.1秒上下,读取加修改操作增长到0.2~0.3秒之间,持续时间约30秒左右,随后读取操作耗时回落并稳定在0.01秒上下,读取加修改操作耗时稳定在0.03秒上下。

执行读取、读取加修改、插入操作是执行online DDL

  • 开启30个线程,其中10个线程中的每个线程以10次/秒的速率访问数据库,通过ID作为查询条件做select操作;另外10个线程中的每个线程以10次/秒的速率先通过ID查询数据,再以ID作为条件执行update操作;最后10个线程中的每个线程以10次/秒的速率执行insert操作。
  • 同时执行online DDL语句。
  • 在执行online DDL前,读取操作的单个耗时在0.01秒上下,偶发延迟到0.03~0.05秒;读取加修改操作的单个耗时在0.03秒上下,偶发延迟到0.05秒;写入操作的单个耗时在0.2秒上下,且较为稳定。
  • 在执行online DDL过程中,开始阶段读取耗时增加到0.1秒以上,读取加修改操作的耗时增加到0.3秒上下,写入操作的耗时增加到0.4秒上下,约20秒后三种操作的耗时回落至操作前水平,但写入操作偶发延迟最长达8秒。

结论

online DDL确实将MySQL线上大表的修改操作实现为一种可能,且对读取和修改操作无太大影响,但对于写入操作会有偶发性的严重影响。

所以使用前最好根据自身的服务状况,在预发环境做充分测试后再到生产环境执行。

引用鸣谢:

  1. 张哈希 https://juejin.cn/post/6919646430567071751?utm_source=gold_browser_extension (MySQL 大表添加一列):online DDL简介-参数介绍
  2. MySQL官方文档 https://dev.mysql.com/doc/
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!