码迷,mamicode.com
首页 > 数据库 > 详细

MySQL学习(八)删除表数据

时间:2020-02-21 14:47:41      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:复用   idt   保护   产生   数据文件   color   临时文件   ddl   去掉   

表空洞的产生

删除某个行数据 或删除某个页

????如下图所示,这个删除过程只是标记了某行的位置为删除,假如此时在300与600之间插入了一行数据,那么 技术图片 同理,当删除某个页时,该页就会被复用。所以当删除某一行或页时空间并不会被回收,而是会被复用,这些可以复用,而没有被使用的空间,看起来就像是“空洞”。

插入数据产生空洞

????不仅是删除数据,插入数据的时候也会产生空洞, 技术图片 ????例如上图,插入一行索引为550 的记录,经过页分裂后会产生新的页,而旧的pageA 会产生页空洞,如果能够把这些空洞去掉,就能达到收缩表空间的目的。而重建表就,就可以达到这样的目的。

表空洞优化过程

重建表

MySQL5.5之前(不是Online的)

????重建表的作用是使我们的空间更加紧凑,提高空间的利用率,你可以想到的方法应该是使用一张临时表,将表的数据条条从久表迁移过去,然后新表替换久表就行了。这里,你可以使用alter table A engine=InnoDB命令来重建表。在MySQL 5.5版本之前,这个命令的执行流程跟我们前面描述的差不多,区别只是这个临时表B不需要你自己创建,MySQL会自动完成转存数据、交换表名、删除旧表的操作。 ????操作如下 : 技术图片 ????需要注意的是当表在重建的时候,是不允许DDL 的!

MySQL5.5以后(是Online的)

????MySQL5.5以后的重建表操作,此时要是有DDL操作,先会记录到日志文件中去,之后再运用在新文件中,具体的过程如下 :

  1. 建立一个临时文件,扫描表A主键的所有数据页;

  2. 用数据页中表A的记录生成B+树,存储到临时文件中;

  3. 生成临时文件的过程中,将所有对A的操作记录在一个日志文件(row log)中,对应的是图中state2的状态;

  4. 临时文件生成后,将日志文件中的操作应用到临时文件,得到一个逻辑数据上与表A相同的数据文件,对应的就是图中state3的状态;

  5. 用临时文件替换表A的数据文件。

操作如下 :

技术图片

这样即是表在重建的过程中,依旧可以DDL.

底层实现小疑问

问题: DDL之前是要拿MDL写锁的,这样还能叫Online DDL吗?
下面解答来自参考资料

????确实,图4的流程中,alter语句在启动的时候需要获取MDL写锁,但是这个写锁在真正拷贝数据之前就退化成读锁了。

为什么要退化呢?为了实现Online,MDL读锁不会阻塞增删改操作。

那为什么不干脆直接解锁呢?为了保护自己,禁止其他线程对这个表同时做DDL。

而对于一个大表来说,Online DDL最耗时的过程就是拷贝数据到临时表的过程,这个步骤的执行期间可以接受增删改操作。所以,相对于整个DDL过程来说,锁的时间非常短。对业务来说,就可以认为是Online的。

需要补充说明的是,上述的这些重建方法都会扫描原表数据和构建临时文件。对于很大的表来说,这个操作是很消耗IO和CPU资源的。因此,如果是线上服务,你要很小心地控制操作时间。如果想要比较安全的操作的话,我推荐你使用GitHub开源的gh-ost来做。

参考资料

  • 《MySQL45讲》

MySQL学习(八)删除表数据

标签:复用   idt   保护   产生   数据文件   color   临时文件   ddl   去掉   

原文地址:https://www.cnblogs.com/Benjious/p/12341157.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!