• MySQL5.6 Online DDL


    MySQL5.6 Online DDL

    简单介绍

    ddl包含了copy和inplace方式,对于不支持online的ddl操作采用copy方式。对于copy方式,copy过程中全程锁表,不允许写(rename阶段会禁止读写),比如修改表字段的类型,包括修改长度,对于inplace方式,mysql内部以是否修改记录格式为基准也分为两类,一类需要重建表(重新组织记录,重建过程中会建立临时ibd文件),比如添加索引、添加/删除列、修改列NULL/NOT NULL属性等;另外一类是只需要修改表的元数据,比如删除索引、修改列名、修改列默认值、修改列自增值等。MySQL将这两类方式分别称为rebuild方式和no-rebuild方式。

    online ddl主要包括3个阶段,prepare阶段,ddl执行阶段,commit阶段,rebuild方式比no-rebuild方式实质多了一个ddl执行阶段,prepare阶段和commit阶段类似。

    prepare阶段
    1. 创建新的临时frm文件(MySQL server层建的)
    2. 升级MDL_SHARED_UPGRADABLE到EXCLUSIVE-MDL锁,禁止读写
    3. 根据alter类型,确定执行方式(copy,online-rebuild,online-norebuild)
    4. 更新数据字典的内存对象
    5. 分配row_log对象记录增量
    6. 生成新的临时ibd文件

    此阶段主要是innodb引擎做一些校验,分配空间,初始化等操作,时间不长,对于用户感觉不出来禁止读写

    ddl执行阶段
    1. 降级EXCLUSIVE-MDL锁到MDL_SHARED_UPGRADABLE,允许读写
    2. 扫描old_table的聚集索引每一条记录rec
    3. 遍历新表的聚集索引和二级索引,逐一处理
    4. 根据rec构造对应的索引项
    5. 将构造索引项插入sort_buffer块
    6. 将sort_buffer块插入新的索引
    7. 处理ddl执行过程中产生的增量(仅rebuild类型需要)
    commit阶段
    1. 升级MDL_SHARED_UPGRADABLE到EXCLUSIVE-MDL锁,禁止读写
    2. 重做最后row_log中最后一部分增量
    3. 更新innodb的数据字典表
    4. 提交事务(刷事务的redo日志)
    5. 修改统计信息
    6. rename临时idb文件,frm文件
    7. 变更完成

    对于norebuid模式(如删除索引),InnoDB二级索引只需要更新内部视图,并标记这个索引的空间可用,去掉数据库元数据上该索引的定义即可,都是在原表上操作,不需要重建与copy数据,所以速度非常快,基本可以忽略阻塞读写的时间

    row_log说明
    1. Row Log中记录的是Online创建索引期间,原表上的DML操作这些操作包括:ROW_OP_INSERT;ROW_OP_DELETE_MARK等
    2. Row Log以Block的方式存储,若DML较多,那么Row Logs可能会占用多个Blocks。row_log_t结构中包含两个指针:head与tail,head指针用于读取Row Log,tail指针用于追加写新的Row Log
    3. 在重用Row Log时,算法遵循一个原则:尽量减少索引树加锁的时间(索引树加X锁,也意味着表上禁止了新的DML操作)
    索引树加锁的场景
    1. 在重用Row Log跨越新的Block时,需要短暂加锁;
    2. 若应用的Row Log Block是最后一个Block,那么一直加锁应用最后一个Block,由于禁止了新的DML操作,因此此 Block应用完毕,新索引记录与聚簇索引达到一致状态,重用阶段结束;
    3. 在应用中间Row Log Block上的row log时,无需加锁,新的DML操作仍旧可以进行,产生的row log记录到最后一个Row Log Block之上;
    源码分析

    虽然画了上面的图,但是里面的细节还是有很多的不懂,不明白,还是只能知道大概的流程,对于每一个点都是一个很深的知识点,commit阶段也还没有整理,待补

  • 相关阅读:
    [百度百科]PCI-E的速度
    Oracle 高版本往低版本备份恢复的方法
    PHP-Java-Bridge使用笔记
    Delphi获取其它进程窗口句柄的3种方法
    二层交换机当三层交换机,使用单臂路由实现二层交换机上的VLAN互通
    Python下科学计算包numpy和SciPy的安装【原创】
    OpenGL: 你不知道的左右手坐标系
    Delphi XE7的安卓程序如何调用JAVA的JAR,使用JAVA的类?
    科普:UTF-8 GBK UTF8 GB2312 之间的区别和关系
    phpmyadmin #1045 #2002 无法登录 MySQL 服务器的解决方
  • 原文地址:https://www.cnblogs.com/muzhao/p/9882117.html
Copyright © 2020-2023  润新知