MySQL--各版本DDL 操作总结
MySQL 5.5 DDL
在MySQL 5.5版本前,所有DDL操作都使用Copy Table的方式完成,操作过程中原表数据库不允许写入,只能读取,在MySQL 5.5版本中引入FIC(Fast index creation)特性。
FCI 操作流程:
(1)对表加共享S锁,允许其他会话读操作,但禁止写操作,
(2)根据当前表数据创建索引,
(3)新索引创建完成,解除S锁,允许读写。
FCI 优点:
(1)创建索引不需要拷贝整表数据,创建速度快,
(2)创建索引过程中,可以快速中止。
FCI限制:
(1)FCI特新仅限于复制索引,不试用于聚集索引,
(2)索引创建期间,表只允许读不允许写。
在MySQL 5.6.7版本前,DDL操作主要有copy和inplace两种方式,两种方式全程都需要锁表禁止写操作,允许部分时间段的读操作,inplace方式仅支持添加和删除索引两种方式。
copy方式:
(1)新建带索引的临时表
(2)锁原表,禁止DML,允许查询
(3)将原表数据拷贝到临时表(无排序,一行一行拷贝)
(4)进行rename,升级字典锁,禁止读写
(5)完成创建索引操作
inplace方式:
(1)新建索引的数据字典
(2)锁表,禁止DML,允许查询
(3)读取聚集索引,构造新的索引项,排序并插入新索引
(4)等待打开当前表的所有只读事务提交
(5)创建索引结束
MySQL 5.6 DDL
在MySQL 5.6.7版本后,引入了row_log来记录DDL期间写操作所产生的日志,因此除DDL操作开始和结束的两小段时间需要对表持EXCLUSIVE-MDL锁禁止读写外,其余DDL操作阶段允许其他回话对表进行读写,因此可算作ONLINE DDL。
对于ONLINE DDL操作,同样包含copy和inplace方式,而对于inplace方式,又可以细分为rebuild方式和no-rebuild方式,rebuild方式指需要重新组织记录的操作如添加删除列或交换列顺序等操作,而no-rebuild方式指不会导致记录格式发生变化的操作如删除和添加索引。
ONLINE DDL可分为三个阶段操作:
Prepare阶段:
1.创建新的临时frm文件
2.持有EXCLUSIVE-MDL锁,禁止读写
3.根据alter类型,确定执行方式(copy,online-rebuild,online-norebuild)
4.更新数据字典的内存对象
5.分配row_log对象记录增量
6.生成新的临时ibd文件
ddl执行阶段:
1.降级EXCLUSIVE-MDL锁,允许读写
2.扫描old_table的聚集索引每一条记录rec
3.遍历新表的聚集索引和二级索引,逐一处理
4.根据rec构造对应的索引项
6.将构造索引项插入sort_buffer块
6.将sort_buffer块插入新的索引
7.处理ddl执行过程中产生的增量(仅rebuild类型需要)
commit阶段
1.升级到EXCLUSIVE-MDL锁,禁止读写
2.重做最后row_log中最后一部分增量
3.更新innodb的数据字典表
4.提交事务(刷事务的redo日志)
5.修改统计信息
6.rename临时idb文件,frm文件
7.变更完成
Online DDL期间产生Row Log会按照Block来存放和处理,回放Row Log时按照Block来处理,一个Block回放完后处理下一个Block,只有到达最后一个Block时才会锁表,保证最后一个Block完成后新数据和老数据保持一致,因此Online DDL期间产生大量Row Log不会导致表被长时间锁定。
仅需要修改元数据的DDL操作:
(1)设置列默认值
(2)设置自增列的自增值
(3)删除索引
可以采用Online no-rebuild方式的DDL操作:
(1)添加索引
可以采用Online rebuild方式的DDL操作:
(1)添加列
(2)删除列
(3)交换列顺序
(4)修改列NULL-NOTNULL属性
(5)修改表ROW-FORMAT
(6)添加修改主键
只能采用Copy方式的DDL操作:
(1)修改列类型
(2)转换字符集
(3)Optimize table
(4)删除主键
PS: 从MySQL 5.6.17版本后,Optimize table可以采用Inplace方式操作。
Online DDL操作相关参数:
(1)innodb_sort_buffer_size:用来存放Row log的Block大小由参数innodb_sort_buffer_size控制。
(2)innodb_online_alter_log_max_size:控制整个DDL期间产生Row log的文件上限值,当产生的Row Log超过该上限值,则DDL操作失败,并回滚该期间所有未提交的并发DML操作。
(3)innodb_sort_buffer_size:在DDL执行期间Row Log会写入到一个日志文件,该日志文件每次按照innodb_sort_buffer_size来扩展。
(4)old_alter_table,当该参数被启用后,所有Alter操作将使用COPY方式操作。
唯一索引的BUG:
(未找到该BUG出处)MySQL 在处理Row Log的时候存在BUG,会导致创建的唯一索引中可能存在不唯一KEY值的情况。
Duplicate entry问题:
在进行Online DDL操作过程中,可能遇到Duplicate entry的报错,但数据和修改命令都正常,该问题解释:
When running an online DDL operation, the thread that runs the ALTER TABLE statement applies an “online log” of DML operations that were run concurrently on the same table from other connection threads. When the DML operations are applied, it is possible to encounter a duplicate key entry error (ERROR 1062 (23000): Duplicate entry), even if the duplicate entry is only temporary and would be reverted by a later entry in the “online log”. This is similar to the idea of a foreign key constraint check in InnoDB in which constraints must hold during a transaction.
连接:https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-limitations.html
MySQL 5.7 DDL
在MySQL 5.7版本中,增加以下新功能:
支持修改索引名操作
操作语法:ALTER TABLE t1 RENAME INDEX idx1 to idx2;
该操作仅需要修改元数据信息和刷新缓存,因此修改操作能快速完成。
支持在线增加VARCHAR列的长度。
在Innodb存储引擎中,字节长度小于255的列使用1个字节来标识列长,而对于字节长度超过255的列需要使用2个字节来标识列长。
1、如果VARCHAR列长度仅在0-255或255-65535区间发生变化时,仅需要修改元数据信息而不需要对表进行Inplace操作,因此修改操作能快速完成。
语法:alter table tb002 ALGORITHM=INPLACE, CHANGE COLUMN c4 c4 varchar(500);
或: alter table tb002 ALGORITHM=INPLACE, modify c4 varchar(600);
2、如果VARCHAR列长度从0-255区间变化到255-65535区间,则只能使用COPY方式,不允许并发DML。
3、如果缩小VARCHAR列的长度,也只能使用COPY方式,不允许并发DML。
支持使用INPLACE方式增加主键
语法:ALTER TABLE tb002 ADD PRIMARY KEY(id),ALGORITHM=INPLACE;
MySQL DDL总结:
虽然MySQL 5.6和5.7版本提供了Online DDL操作,但Online DDL仍存在以下问题:
(1)主从复制延迟,只有主库上DDL执行成功才会写入到binlog中,而DDL操作在从库上不能并发执行,因此即使主库执行DDL时允许并发DML操作,对于大表操作,仍会引发严重的复制延迟。
(2)主库执行Online DDL时,不能根据负载暂停DDL操作。
(3)使用Inplace方式执行的DDL,发生错误或被KILL时,需要一定时间的回滚期,执行时间越长,回滚时间越长。
(4)使用Copy方式执行的DDL,需要记录过程中的undo和redo日志,同时会消耗buffer pool的资源,效率较低,优点是可以快速停止。
(5)Online DDL并不是所有时间段的Online,在特定时间段需要加元数据锁或其他锁。
(6)允许并发DML的DDL,可能会导致Duplicate entry问题。
DDL 建议:
1、对于并发操作较高的表,无论表数据量多少,不能在业务高峰期操作,
2、对于大表和较大表,如果对复制延迟和主库性能敏感,建议改为gh-ost或pt-osc工具,
3、对于包含唯一索引创建的DDL,不能使用gh-ost或pt-osc工具,
4、能业务低峰期操作的DDL,都尽量安排在业务低峰期进行。
MySQL--各版本DDL 操作总结的更多相关文章
- MySQL DDL--MySQL 5.7版本Online DDL操作
主键索引维护 1.新增主键索引 ## 可以使用ALGORITHM=INPLACE+LOCK=NONE方式,操作期间允许读写. ALTER TABLE tb001 ADD PRIMARY KEY (ID ...
- MySQL在线大表DDL操作
在线大表DDL操作的方法: 1.主从架构轮询修改 需要注意: a.主库会话级别的记录binglog的参数关闭 b.500\502错误异常捕捉 c.检查备库的second behind master是否 ...
- MySQL在线大表DDL操作 (转)
http://www.cnblogs.com/janehoo/p/5382474.html 线大表DDL操作的方法: 1.主从架构轮询修改 需要注意: a.主库会话级别的记录binglog的参数关闭 ...
- 【科普】MySQL中DDL操作背后的并发原理
一. 简介 DQL:指数据库中的查询(select)操作. DML:指数据库中的插入(insert).更新(update).删除(delete)等行数据变更操作. DDL:指数据库中加列(add co ...
- 闯祸了,生成环境执行了DDL操作《死磕MySQL系列 十四》
由于业务随着时间不停的改变,起初的表结构设计已经满足不了如今的需求,这时你是不是想那就加字段呗!加字段也是个艺术活,接下来由本文的主人咔咔给你吹. 试想一下这个场景 事务A在执行一个非常大的查询 事务 ...
- MySQL InnoDB Online DDL学习
MySQL Online DDL这个新特性是在MySQL5.6.7开始支持的,更早期版本的MySQL进行DDL对于DBA来说是非常痛苦的.现在主流版本都集中在5.6与5.7,为了更好的理解Online ...
- MySql的相关资操作
01-MySql的前戏 MySql的前戏 在学习Mysql之前,我们先来想一下一开始做的登录注册案例,当时我们把用户的信息保存到一个文件中: #用户名 |密码root|123321 alex|12 ...
- MySQL安装与初步操作
MySQL是一款出色的中小型关系数据库,做Java Web开发时,要做到数据持久化存储,选择一款数据库软件自然必不可少. 由于MySQL社区版开元免费,功能比较强大,在此以MySQL为例,演示MySQ ...
- MySQL5.7 慢查询+DDL操作堵塞查询
数据库版本: mysql> select @@version; +------------+ | @@version | +------------+ | 5.7.26-log | +----- ...
随机推荐
- Qt与FFmpeg联合开发指南(三)——编码(1):代码流程演示
前两讲演示了基本的解码流程和简单功能封装,今天我们开始学习编码.编码就是封装音视频流的过程,在整个编码教程中,我会首先在一个函数中演示完成的编码流程,再解释其中存在的问题.下一讲我们会将编码功能进行封 ...
- BuautifulSoup4库详解
1.BeautifulSoup4库简介 What is beautifulsoup ? 答:一个可以用来从HTML 和 XML中提取数据的网页解析库,支持多种解析器(代替正则的复杂用法) 2.安装 p ...
- Spring Security简明实践及相关国际化处理
别人的都是最佳实践,因为我目前的设置没有按照参考文档推荐,还是采用DelegatingFilterProxy,所以我只能说简明实践.先贴我的applicationContext-security.xm ...
- ruby1.9.2 +windowxp
ruby1.9.2 install on the window xp 1:在公司上網是有windows代理的(ntlm),而rails又都是gem安裝,對于接觸rails不多的人來時真是一場災難,我是 ...
- 判断某个方法是否存在,解析php函数function_exists (),method_exists()与is_callable()的区别
php函数function_exists (),method_exists() 与is_callable()的区别在哪? 先来讲下后两个:method_exists() 与is_callable(): ...
- C# 获取当前年份的周期,周期所在日期范围
最近有一个项目要用到年份周期,用于数据统计图表展示使用,当中用到年份周期,以及年份周期所在的日期范围.当初设想通过已知数据来换算年份周期,经过搜索资料发现通过数据库SQL语句来做,反而更加复杂.现在改 ...
- mvc中路由的映射和实现IHttpHandler挂载
首先我们了解一下一般的方法 我们只需要在web.config配置文件中做映射处理即可. 第一种形式: <system.web> <urlMappings enabled=" ...
- 关于 JavaScript 中的复制数组
之前在写扫雷的时候,因为需要用到二维数组,当时就在复制数组这里出现了问题,所以记录一下. 当我们在需要复制数组的时候一定需要注意,数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针, ...
- Egg Dropping Puzzle问题的分析
首先,基本问题是这样:You are given two eggs, and access to a 100-storey building. The aim is to find out the h ...
- float之脱离文档流
所谓的文档流:指的是元素在排版过程中,元素自动从左到右,从上到下的顺序排列. 脱离文档流:也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当做脱离文档流的元素不存在而进行定位 只有绝对定位 ...