MySQL Online DDL的改进与应用
1 早期DDL实现原理(5.6.7之前 )
- copy table方式
- 新建跟原表格一致的临时表,并在该临时表上执行DDL语句
 - 锁原表,不允许DML,允许查询
 - 逐行数据从原表拷贝到临时表中(这个过程是没有排序的)
 - 拷贝结束后,原表禁止读操作,也就是原表此时不提供读写服务
 - 进行rename操作,完成DDL过程
 
 - inplace方式(fast index creation,仅针对索引的创建跟删除)
- 新建frm临时文件
 - 锁原表,不允许DML,允许查询
 - 按照聚集索引的顺序,查询数据,找到需要的索引列数据,排序后插入到新的索引页中
 - 原表禁止读操作,也就是原表此时不提供读写服务
 - 进行rename操作,替换frm文件,完成DDL过程
 
 
inplace在copy table的基础上做了一个较大的改进,则是不需要copy整个表格,只需要在原来的ibd文件上,新建所需要的索引页,这个过程比copy table节约极大的IO资源占用 且 DDL SQL执行速度大大提高,减少了该表格不提供写服务的时长。但是inplace仅支持索引的创建于删除,不支持其他的DDL操作,其他的DDL操作,仍然是copy table方式执行。
2 Online DDL实现原理

- PREPARE
- 创建新的临时frm文件
 - 持有EXCLUSIVE_MDL锁,禁止读写
 - 根据alter类型,确定执行方式(copy,rebuild,no-rebuild)
 - 更新数据字典的内存对象
 - 若是需要rebuild,分配row_log对象记录的增量
 - 若是需要rebuild, 生成新的临时ibd文件
 
 - EXECUTE
- 如果是仅修改元数据:
- 这部分无操作
 
 - 其他,则是:
- 降低EXCLUSIVE-MDL锁,允许读写(copy 不允许写)
 - 记录ddl执行过程中产生的增量row-log(仅rebuild类型需要)
 - 扫描old_table的聚集索引每一条记录record
 - 遍历新表的聚集索引和二级索引,逐一处理
 - 根据record构造对应的索引项
 - 将构造索引项插入sort_buffer块
 - 将sort_buffer块插入新的索引
 - 把row-log中的操作应用到新临时表中,应用到最后一个Block
 
 
 - 如果是仅修改元数据:
 - COMMIT
- 升级到EXECLUSIVE-MDL锁,禁止读写
 - 重做最后一部分的row_log增量
 - 更新innodb的数据字典表
 - 提交事务,写redo日志
 - 修改统计信息
 - rename 临时的ibd文件、frm文件
 - DDL完成
 
 
- Online DDL期间,查询和DML操作在多数情况下可以正常执行,对表格的锁时间也会大大减少,尽可能的保证数据库的可扩展性;
 - 允许 in-place 操作的 DDL,避免重建表格占用过多磁盘IO及CPU资源,减少对数据库的整体负荷,使得在DDL期间,能够维持数据库的高性能及高吞吐量;
 - 允许 in-place 操作的 DDL,比需要COPY到临时文件的操作要更少占用buffer pool,避免以往DDL过程中性能的临时下降,因为以前需要拷贝数据到临时表,这个过程会占用到buffer pool ,导致内存中的部分频繁访问的数据会被清理出去。
 
3 Online DDL涉及参数及选项
3.1 innodb_online_alter_log_max_size
3.2 Online DDL语法
- Alter table …. , ALGORITHM [=] {DEFAULT|INPLACE|COPY}, LOCK [=] { DEFAULT| NONE| SHARED| EXCLUSIVE }
 
3.3 lock 选项
LOCK=EXCLUSIVE- 对整个表格添加独占锁(x锁),不允许查询跟修改操作
 
LOCK=SHARED- 对整个表格添加(s锁),允许查询操作,但是不支持数据变更操作
 
LOCK=NONE- 不添加锁,既允许查询操作,也支持数据库变更操作,该模式下并发最好
 
LOCK=DEFAULT- 没有指定LOCK的时候,则是默认为这个选项
 - 根据DDL的操作类型,最小程度的加锁,尽可能支持查询及0DML操作
 - 首先判断当前操作是否可以使用NONE模式,如果不能,判断是否可以使用SHARED模式,如果不能,判断是否可以使用
EXCLUSIVE模式 
3.4 ALGORITHM选项
ALGORITHM=INPLACEALGORITHM=COPY
4 Online DDL支持语法情况
- In-Place?
- 说明: 是否支持  
ALGORITHM=INPLACE 
 - 说明: 是否支持  
 - Rebuilds Table?
- 说明:是否会重建表格
 - 重建表格分为两种方式:INPLACE跟COPY (原地修改或者复制到临时文件修改)
 - 如果支持 
ALGORITHM=INPLACE,那么则是原地修改 INPLACE(淡黄色标记) - 如果不支持 
ALGORITHM=INPLACE,那么则是COPY,拷贝到临时文件修改,并且不支持UPDATE DELETE INSERT操作(深褐色标记) 
 - Permits Concurrent DM
- 说明: 是否支持在DDL期间并发对该表格操作DML SQL
 - 新增空间索引及全文索引时,不支持DML操作
 - 当允许时,可以通过LOCK选项来控制是否要提供查询或者修改操作
 - LOCK=NONE,支持查询跟UPDATE INSERT DELETE操作
 - LOCK=SHARED,仅支持查询
 - Only Modifies Metadata?
 - 是否只修改元数据
 
 

5 测试记录
5.1 4个典型DDL操作分析

5.1.1 DDL测试内容
- 测试DB环境:表格名 tbddl,表格大小:1G ,500W行记录
 - 测试流程:开启事务查询,不提交 => 执行DDL => 提交查询事务 => 执行DML =>开启事务,执行DML不提交 =>提交DML
 - 测试DDL SQL
- ALTER TABLE tbddl MODIFY COLUMN ItemId VARCHAR(20);
 - ALTER TABLE tbddl ADD xinysu int;
 - CREATE INDEX IX_PROID ON tbddl (providerid);
 - ALTER TABLE tbddl ALTER COLUMN xinysu SET DEFAULT 123456;
 - ALTER TABLE tbddl ALTER COLUMN ItemId VARCHAR(50); #UTF8字符集,3个字节一个字符,50个字符则是150个字节,小于256bytes
 - ALTER TABLE tbddl ALTER COLUMN ItemId VARCHAR(100); #UTF8字符集,3个字节一个字符,100个字符则是300个字节,大于256bytes
 
 - 测试关注点
- 启动与关闭 old_alter_table
 - prepare,commit阶段的锁是怎么样的
 - excute阶段的锁是怎么样的
 - 执行期间服务器的性能情况(zabbix监控)
 - 执行期间数据库的并发情况(sysbench压测)
 
 
5.1.2 DDL测试结论
- 当 3M<256,3N<256,存储长度的字节不需要变化,都为1,则不需要变动行记录,仅需要修改元数据;
 - 当 3M>256,3N>256,存储长度的字节不需要变化,都为2, 则不需要变动行记录,仅需要修改元数据;
 - 当 3M<256,3N>256,存储长度的字节需要变化,由1变2, 则需要变动行记录,Online DDL使用COPY TABLE方式;
 - 当 3M>256,3N>256,存储长度的字节需要变化,由2变1,则需要变动行记录,Online DDL使用COPY TABLE方式
 

5.2 同表格多个DDL处理
- 除了个别不支持inplace的DDL语句,其他DDL语句在执行期间是不会加X锁的,也就是表格仍然提供DML操作
 - 锁的粒度,同个DDL语句中,按照最高级别的锁处理
 - 维护的方便性
 
- 为啥copy table单独出来呢?
- 因为这一类操作过程中是不允许DML操作的,建议把这一类的合成单独一条DDL SQL执行,不与IPLACE的DDL SQL合并;
 
 - 为啥iplace的要分为2类呢?
- 方便维护
 - 仅元数据修改的DDL较快执行结束,为了方便管理维护,不至于所有SQL贴一堆,仅元数据修改的DDL语句归一类
 - 需要REBUILD的归一类,避免重复rebuild,浪费磁盘IO跟CPU资源。
 
 

5.3 DDL执行期间数据库性能异常处理
- show processlist;
 - kill 进程id;
 
5.4 DDL执行期间数据库宕机
5.5 DDL对主从的影响
- 使用注意
- 在从库严重落后主库的情况下,可以开启该参数实现多线程并行执行
 - 在业务量低的数据库,不建议开启,从库同步性能反而会比拖累
 
 - 配置注意
- 注意 master_info_repository relay_log_info_repository 设置为 table,默认是写入mater_info.log 及 relay_info.log ,刷下这两个文件的频率带来的性能影响比较大,据 姜承骁姜老师 压测,性能相差 20-50%间
 - slave_parallel_workers 建议设置为从库 核心 数
 - slave_parallel_type
- database,不同库的事务,触发从库并行回放
 - logical_clock,组提交事务,按照组提交设置,从库并行回放,如果是为了改善DDL的滞后情况,应使用这个配置。
 
 
 
6 Online DDL注意事项
- 磁盘空间
- rebuild 的时候,datadir空间是否足够
- 因为会拷贝ibd文件,所以要确保空间足够
 
 - rebuild 的时候,innodb_online_alter_log_max_size是否足够
- rebuild过程中,产生的DML涉及到行记录变更日志,是否足够存储
 
 - inplace的时候,考虑tmpdir空间是否足够
 
 - rebuild 的时候,datadir空间是否足够
 - ddl对从库延迟的影响是否可以接受
- 主库online DDL的过程中,由于没有commit,所以其他并发操作可以正常同步到从库
 - 主库commit后,DDL同步到从库
 - 由于从库是单线程执行SQL_THREAD,假设DDL执行过程需要1个小时,那么从库将会滞后1小时+
 - 是否允许从库的滞后,如果不允许,可以通过并行复制来优化处理
 
 - row-log会检查重复值或者修改冲突吗?
- 会根据主键及唯一约束来检查
 
 - copy table ,inplace下如何暂停DDL操作
- show full processlist;
 - kill id; #( DDL SQL的id号)
 - 这里kill完后,仍然可以再次正常执行DDL,不会存在冲突,其创建的临时idb及frm文件会自动删除
 
 - copy table ,inplace下宕机
- 这两种情况下宕机后,没有完成的DDL语句不会继续执行
 - 但是,其生成的frm跟idb临时文件不会被删除,可以手动删除,也可以不手动删除,即使不删除,也不会影响再次执行DDL
 - 但建议mysql服务后,删除无用的临时文件
 
 - 同个表格多个DDL语句,不要一个个执行
- 请按照是否支持inplace及是否需要rebuild分类合并执行
 
 - 如何查看ddl进度(未解决)
- 如果有rebuild,则是通过ibd文件的增长来评估;但是如果是inplace,如何查看呢?有没有什么比较好的方式查看?performance_schema是否有提供相应的查询方式?
 
 
MySQL Online DDL的改进与应用的更多相关文章
- 详谈 MySQL Online DDL
		
作为一名DBA,对数据库进行DDL操作非常多,如添加索引,添加字段等等.对于MySQL数据库,DDL支持的并不是很好,一不留心就导致了全表被锁,经常搞得刚入门小伙伴很郁闷又无辜,不是说MySQL支持O ...
 - mysql online  ddl
		
大家知道,互联网业务是典型的OLTP(online transaction process)应用,这种应用访问数据库的特点是大量的短事务高并发运行.因此任何限制高并发的动作都是不可接受的,甚至 ...
 - [资料收集]MySQL在线DDL工具pt-online-schema-change
		
MySQL在线DDL工具pt-online-schema-change pt-online-schema-change使用说明(未完待续) 官网
 - 关于MySQL Online DDL
		
1. Online DDL 在 MySQL 5.1 (带InnoDB Plugin)和5.5中,有个新特性叫 Fast Index Creation(下称 FIC),就是在添加或者删除二级索引的时候, ...
 - MySQL在线DDL gh-ost 使用说明
		
背景: 作为一个DBA,大表的DDL的变更大部分都是使用Percona的pt-online-schema-change,本文说明下另一种工具gh-ost的使用:不依赖于触发器,是因为他是通过模拟从库, ...
 - MySQL使用DDL语句创建表
		
一.使用DDL语句创建表 DDL语言全面数据定义语言(Data Define Language) 主要的DDL动词: CREATE(创建).DROP(删除).ALTER(修改) TRUNCATE(截断 ...
 - MySQL Online DDL导致全局锁表案例分析
		
MySQL Online DDL导致全局锁表案例分析 我这边遇到了什么问题? 线上给某个表执行新增索引SQL, 然后整个数据CPU打到100%, 连接数暴增到极限, 最后导致所有访问数据库的应用都奔溃 ...
 - MySQL在线DDL工具 gh-ost
		
一.简介 gh-ost基于 golang 语言,是 github 开源的一个 DDL 工具,是 GitHub's Online Schema Transmogrifier/Transfigurator ...
 - 【科普】MySQL中DDL操作背后的并发原理
		
一. 简介 DQL:指数据库中的查询(select)操作. DML:指数据库中的插入(insert).更新(update).删除(delete)等行数据变更操作. DDL:指数据库中加列(add co ...
 
随机推荐
- Vue开源项目库汇总
			
最近做了一个Vue开源项目库汇总,里面集合了OpenDigg 上的优质的Vue开源项目库,方便移动开发人员便捷的找到自己需要的项目工具等,感兴趣的可以到GitHub上给个star. UI组件 elem ...
 - jquery 的基础知识,以及和Javascript的区别
			
想到之前所学的javascript 我们会想到这几个方面:找元素: 操作内容: 操作属性:操作样式:统一操作元素: jquery 也是从这几个方面来学习的. <head> <meta ...
 - Pdf File Writer 中文应用(PDF文件编写器C#类库)
			
该文由小居工作室(QQ:2482052910) 翻译并提供解答支持,原文地址:Pdf File Writer 中文应用(PDF文件编写器C#类库):http://www.cnblogs.com/ ...
 - JSOI2015 一轮省选 个人题解与小结
			
T1: 题目大意:现有一个以1为根节点的树,要求从1开始出发,经过下面的点然后最终要回到根节点.同时除了根节点之外各点均有一个权值(即受益,每个点上的收益只能拿一次,且经过的话必须拿),同时除了根节点 ...
 - iOS截屏保存至相册
			
#pragma mark 截屏并保存至相册 -(void)screenShotsComplete:(void(^)(UIImage * img)) complete { CGSize imageSiz ...
 - windows phone 8.1开发:触控和指针事件1
			
原文出自:http://www.bcmeng.com/windows-phone-touch/ UIElement类的触控事件: ManipulationStarting:当用户将手指放在 IsMan ...
 - BootStrap入门教程 (二)
			
文本转自 http://www.cnblogs.com/ventlam/archive/2012/05/29/2520807.html 上讲回顾:Bootstrap的手脚架(Scaffolding)提 ...
 - 使用CEF(CEFGLUE)作为您的客户端UI(一)
			
背景: 本人是一名C#开发者,而作为C#开发者,做客户端应用中最头痛的一件事就是没有一个好的UI解决方案.WinFrom嘛,效率虽然还不错,但是做一些特殊的效果,完全应付不来,比如透明控件.比FPS太 ...
 - iOS开发之UIDevice通知
			
UIDevice类提供了一个单例对象,它代表着设备,通过它可以获得一些设备相关的信息,比如电池电量值(batteryLevel).电池状态(batteryState).设备的类型(model,比如iP ...
 - 浅谈MVC缓存
			
缓存是将信息放在内存中以避免频繁访问数据库从数据库中提取数据,在系统优化过程中,缓存是比较普遍的优化做法和见效比较快的做法. 对于MVC有Control缓存和Action缓存. 一.Control缓存 ...