mysql5.6 ddl_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阶段

创建新的临时frm文件(MySQL server层建的)

升级MDL_SHARED_UPGRADABLE到EXCLUSIVE-MDL锁,禁止读写

根据alter类型,确定执行方式(copy,online-rebuild,online-norebuild)

更新数据字典的内存对象

分配row_log对象记录增量

生成新的临时ibd文件

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

ddl执行阶段

降级EXCLUSIVE-MDL锁到MDL_SHARED_UPGRADABLE,允许读写

扫描old_table的聚集索引每一条记录rec

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

根据rec构造对应的索引项

将构造索引项插入sort_buffer块

将sort_buffer块插入新的索引

处理ddl执行过程中产生的增量(仅rebuild类型需要)

commit阶段

升级MDL_SHARED_UPGRADABLE到EXCLUSIVE-MDL锁,禁止读写

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

更新innodb的数据字典表

提交事务(刷事务的redo日志)

修改统计信息

rename临时idb文件,frm文件

变更完成

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

row_log说明

Row Log中记录的是Online创建索引期间,原表上的DML操作这些操作包括:ROW_OP_INSERT;ROW_OP_DELETE_MARK等

Row Log以Block的方式存储,若DML较多,那么Row Logs可能会占用多个Blocks。row_log_t结构中包含两个指针:head与tail,head指针用于读取Row Log,tail指针用于追加写新的Row Log

在重用Row Log时,算法遵循一个原则:尽量减少索引树加锁的时间(索引树加X锁,也意味着表上禁止了新的DML操作)

索引树加锁的场景

在重用Row Log跨越新的Block时,需要短暂加锁;

若应用的Row Log Block是最后一个Block,那么一直加锁应用最后一个Block,由于禁止了新的DML操作,因此此 Block应用完毕,新索引记录与聚簇索引达到一致状态,重用阶段结束;

在应用中间Row Log Block上的row log时,无需加锁,新的DML操作仍旧可以进行,产生的row log记录到最后一个Row Log Block之上;

源码分析

4802712944d5c73753e6f777d5cf47b0.png

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值