• MySQL数据的ONLINE DDL操作测试


    最近在研究如何给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线上大表的修改操作实现为一种可能,且对读取和修改操作无太大影响,但对于写入操作会有偶发性的严重影响。

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

    注意事项

    若在执行online DDL过程中,其它数据库访问请求(例如:业务的请求)发生了异常,也会导致online DDL的失败。

    引用鸣谢:

    1. 张哈希 https://juejin.cn/post/6919646430567071751?utm_source=gold_browser_extension (MySQL 大表添加一列):online DDL简介-参数介绍
    2. MySQL官方文档 https://dev.mysql.com/doc/
  • 相关阅读:
    最小二乘法与极大似然估计
    已解决Python向数据库插入数据的字符串中含有单引号或双引号报错
    python、SQL日新增人数统计
    一个插件帮你快速、免费下载两个网站的高清无水印LOGO!
    Linux学习之基础工具一
    Liunx安装Tomcat部署Java项目
    载银纳米TiO2/壳聚糖水凝胶/pH/GSH响应羧甲基壳聚糖水凝胶和纳米凝胶的制备
    order模块给User模块发送http请求
    Spring Boot 还在用 if 校验参数?
    【 数据分析概述与职业操守】——CDA level1
  • 原文地址:https://blog.csdn.net/u011924665/article/details/126901127