InnoDB online DDL与快速索引创建
导读:在MySQL5.6之前版本,Innodb表的许多DDL操作是非常昂贵。许多ALTER TABLE操作的原理是通过创建新的空表,定义被要求的表选项和索引,然后逐行拷贝已存在记录到新表,在插入行时更新索引。在旧表所有行被拷贝完,旧表被删除和那新表被重命名为旧的表名。MySQL5.5,和MySQL5.1 有了InnoDB Plugin,优化了CREATE INDEX和DROP INDEX 避免表的拷贝行为。这个特性被称为Fast index Creation。MySQL 5.6 加强ALTER TABLE操作许多方式来避免拷贝表。另外加强的允许SELECT查询和INSERT, UPDATE,和DELETE(DML)语句被处理当该表正被修改时。这些功能的组合现在被称为online DDL。
语法解读:online DDL操作允许alter table 语句指定ALGORITHM,LOCK 子句。
ALGORITHM=inplace,表示DDL操作在原表上就地操作,ALGORITHM=copy ,表示采用以前方式(复制表)进行DDL 操作。DDL没有指定ALGORITHM子句,MySQL会自动选择每种DDL所允许的ALGORITHM子句(并不是所有DDL在所有情况下都支持每种ALGORITHM,如果两种都支持,默认ALGORITHM=inplace优先选择,如果指定某种DDL在某种情况下不允许的ALGORITHM,该执行的DDL 以失败告终)。
LOCK={default|none|shared|exclusive|}是显式指定alter table 的锁级别,default 表是使用所有DDL在不同情况下的默认的锁级别(也是DDL在不同情况下支持最低级别的锁)。LOCK=none不加锁,允许DML,查询并发(注意LOCK=none不是真正表示执行DDL操作不进行锁,在DDL执行真正执行时,还是加排他锁)。LOCK=SHARED不允许DML并发,允许查询。LOCK=exclusive 不允许 DML并发和查询。(alter table 没有显式指定锁的级别,默认情况使用该DDL允许的默认的最低级别锁<也就是看情况>,如果显式指定的锁是该DDL不允许的级别,该DDL以失败中止)
online DDL工作机制:通过ALGORITHM实现DDL操作是复制表还是在原表就地操作,让DDL尽量影响那些需要改变的数据,而不要操作那些不需改变的数据如:对一列设置默认值,仅对该表.frm修改而涉及数据文件。通过LOCK 实现DML,查询的并发。不管锁是哪种级别,在DDL语句正在准备时和在DDL提交时都是以独占方式访问表。而LOCK不同的级别控制是否允许在online DDL操作之前已发起的DML和查询但没有提交和回滚的事务并发。
DDL的影响范围:有些DDL操作仅影响逻辑文件(对一列设置默认值,仅对该表.frm修改不是数据文件。),有些DDL操作影响整个数据文件(重建主键,需要对整个数据进行新的聚集组织),有些DDL操作影响部分数据文件(新增二级索引,二级索引只有主键的值,只需对主键的值进行重构)。
online DDL执行时间:从上面的分析,我可以知道online DDL的执行时间的长短取决多个方面:
1:online DDL 操作的影响范围的大小。
2:online DDL 操作对象的数据量的大小。
3:online DDL 操作时,当前是否已存在需长时间执行的事务
4:online DDL 操作选取ALGORITHM(inplace不一定比copy快)和LOCK的方式
以上因素要综合考虑,才能使online DDL 操作更顺利和更高效。
OnLine DDL后innodb的索引
5.0和更早版本的MySQL中,在一个已经有很多数据的表上添加或者删除一个索引将非常耗时。CREATE INDEX和DROP INDEX通过创建一个新的空的带有要创建索引的表,然后拷贝存在的行到新表中,同时更新索引,当此时key没有排序时插入条目极慢。在所有的行都被拷贝完成以后,旧表被删除,新表被改名。
一条ALTER TABLE命令创建多个索引是可能的。这相对有效,因为聚簇索引只需要被扫描一次。比如
CREATE TABLE T1(A INT PRIMARY KEY, B INT, C CHAR(1)) ENGINE=InnoDB;
INSERT INTO T1 VALUES
(1,2,'a'), (2,3,'b'), (3,2,'c'), (4,3,'d'), (5,2,'e');
COMMIT;
ALTER TABLE T1 ADD INDEX (B), ADD UNIQUE INDEX (C);
上面的命令将创建表T1,在列A上创建聚簇的主键索引,插入几行,然后在列B和C上创建2个新的索引。如果在ALTER TABLE命令之前有很多行,这个方法将比预先创建带有全部索引的表然后加载数据有效。
你也可以一次只创建一个索引,但是每次聚簇索引都会针对CREATE INDEX扫描一次。在InnoDB中删除索引并不要求表数据的任何拷贝,因此一次删多条或者一次删一条是等价的。
重建InnoDB中的聚簇索引总是要求拷贝表中的数据。比如,如果你创建一个表时没有主键,InnoDB将为你选择一个,它可能是第一个UNIQUE key或者NOT NULL的列,或者一个系统产生的key。如果你在后来定义了一个PRIMARY KEY,数据将不得不拷贝。
2.3 实现
InnoDB有2种类型的索引:聚簇索引和二类索引,由于聚簇索引包含数据值于Btree节点之中,添加或者删除一个聚簇索引涉及到数据的拷贝,并将创建一个新的表的拷贝。一个二类索引实际上只包含索引的key和主键的值,这种类型的索引可以在不用拷贝聚簇索引中数据的情况下创建或者删除。进一步,因为二类索引包含着主键的值,当你改变主键定义的时候,将重新创建聚簇索引,所有的二级索引也将重新创建。
删除一个二类索引是简单的,只有内部的InnoDB系统表和MySQL的数据字典表需要被更新来反应索引不再存在的事实。InnoDB将返回索引所使用的空间给表空间,因此新索引或者额外表的行可以使用这些空间。
要添加一个二类索引到存在的表中,InnoDB扫描表,使用内存Buffer和临时文件按照被索引的列的顺序对行进行排序。然后Btree就被建立起来了,这比以随机顺序插入行时保证key的值有序要有效。 因为Btree节点在满了以后会分裂,按照此种方式构建的索引有一个较高的填充因子,对随后的访问具有较好的效率。
2.4 并发的考虑
测试表明对于主键的修改操作,仅rename阶段会短暂的排它锁。
|
mysql> drop index `PRIMARY` on t1; mysql> show profile for query 43; |
mysql> select * from t1 limit 10; |
右边session2中前面在drop index之后执行了很多条查询,都没有阻塞,仅在session中的rename阶段短暂阻塞。
由于Online DDL原因,DML操作也与上面类似,不会长阻塞。但是如果例如drop primay key等操作没有使用online ddl特性,依然要copy to tmp table,那么依然会像myisam一样对DML阻塞。
对于myisam表创建index时<copy to tmp table>,select只有rename时段堵塞,DML被全程阻塞。
InnoDB online DDL与快速索引创建的更多相关文章
- (转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁
表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...
- MySQL技术内幕InnoDB存储引擎(表&索引算法和锁)
表 4.1.innodb存储引擎表类型 innodb表类似oracle的IOT表(索引聚集表-indexorganized table),在innodb表中每张表都会有一个主键,如果在创建表时没有显示 ...
- MySQL InnoDB存储引擎体系架构 —— 索引高级
转载地址:https://mp.weixin.qq.com/s/HNnzAgUtBoDhhJpsA0fjKQ 世界上只两件东西能震撼人们的心灵:一件是我们心中崇高的道德标准:另一件是我们头顶上灿烂的星 ...
- mysql 优化实例之索引创建
mysql 优化实例之索引创建 优化前: pt-query-degist分析结果: # Query 23: 0.00 QPS, 0.00x concurrency, ID 0x78761E301CC7 ...
- substr函数索引创建测试
技术群里小伙伴,沟通说一条经常查询的SQL缓慢,单表SQL一个列作为条件,列是int数值类型,索引类型默认创建. 一.SQL文本substr函数索引创建测试 ,) nm1 ')需求,将上述SQL执行速 ...
- Database基础(二):MySQL索引创建与删除、 MySQL存储引擎的配置
一.MySQL索引创建与删除 目标: 本案例要求熟悉MySQL索引的类型及操作方法,主要练习以下任务: 普通索引.唯一索引.主键索引的创建/删除 自增主键索引的创建/删除 建立员工表yg.工资表gz, ...
- mysql索引创建和使用细节
最近困扰自己很久的膝盖积液手术终于做完,在家养伤,逛技术博客看到easyswoole开发组成员仙士可博客有关mysql索引方面的知识,自己打算重温下. 正常业务起步数据表数据量较少,不用考虑使用索引, ...
- 数据页结构 .InnoDb行格式、以及索引底层原理分析
局部性原理 局部性原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中. 首先要明白局部性原理能解决的是什么问题,也就是主存容量远远比缓存大, CP ...
- mysql InnoDB引擎是否支持hash索引
看一下mysql官方文档:https://dev.mysql.com/doc/refman/5.7/en/create-index.html , 从上面的图中可以得知,mysql 是支持hash索引的 ...
随机推荐
- AsyncTask onPreExecute方法用于在执行后台任务前做一些UI操作
1.实例化 TableListsTask task = new TableListsTask(ServerIP,"ALL", MenuActivity.this); //第三参 ...
- 与你们分享我学习linux系统的三大妙招
一说到linux,我们就自然会想到企业服务器系统,目前市场上的网络设备都是使用linux内核操作系统,一些网络服务器也是使用linux操作系统下面的服务搭建实现的:目前操作系统这块也基本被linux占 ...
- Java纸牌小demo以及日历小demo
//卡牌类 public class Card { //定义卡牌的点数 public static final String[] cardName = { "3", "4 ...
- IIS 反向代理 golang web开发
一. beego 开发编译 bee run 后会编译成 exe文件 编译生成后发布文件结构为 cmd 运行 cd D:/run beegoDemo.exe run 默认配置端口 不能为 80 跟iis ...
- Django--Uploaded Files以及Handlers
一.表示已经上传的文件(uploaded files)的类 表示已经上传的文件的类有下面几个: class UploadedFile 在文件上传的期间,实际的文件数据被存储在request.FILES ...
- Unity Shader入门教程(一)
参考文献:http://www.360doc.com/content/13/0923/15/12282510_316492286.shtml Unity Shader是着色器,将纹理.网格信息输入,得 ...
- angularjs初窥门径
貌似angularjs出来之后网上各种夸angularjs的好黑jquery. angularjs大致可以分为几个板块:作用域,控制器,指令(主要),路由,依赖注入. 1 作用域 作用域在angula ...
- Linux 文本行列转换
使用awk进行行列转换 假设有一个文件 test ,包含的数据遵循以下格式: 同一行数据,单词之间为1个空格" " 每一行都有同样多的数据,个数相同 处理命令: awk '{for ...
- Jenkins中的一些问题解决(~~不断更新~~)
请使用ctrl+F,查询页面中你需要查找的错误信息(注意空格的输入) 1.错误"error fetching remote repo origin" 本地有多个sshkey,导致构 ...
- (转)完整java开发中JDBC连接数据库代码和步骤
JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.l ...