表空洞的产生

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

????如下图所示,这个删除过程只是标记了某行的位置为删除,假如此时在300与600之间插入了一行数据,那么

同理,当删除某个页时,该页就会被复用。所以当删除某一行或页时空间并不会被回收,而是会被复用,这些可以复用,而没有被使用的空间,看起来就像是“空洞”。

插入数据产生空洞

????不仅是删除数据,插入数据的时候也会产生空洞,

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

表空洞优化过程

重建表

MySQL5.5之前(不是Online的)

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

????操作如下 :

????需要注意的是当表在重建的时候,是不允许DDL 的!

MySQL5.5以后(是Online的)

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

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

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

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

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

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

操作如下 :

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

底层实现小疑问

问题: DDL之前是要拿MDL写锁的,这样还能叫Online DDL吗?

下面解答来自参考资料

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

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

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

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

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

参考资料

《MySQL45讲》

mysql可以复用删除的记录吗_MySQL学习(八)删除表数据相关推荐

  1. mysql每隔俩小时、四小时、八小时进行数据统计

    mysql每隔俩小时.四小时.八小时进行数据统计 需求:我们经常会遇到每隔一分钟.一小时.一天.一个月进行数据统计,遇到如标题所说的统计信息比较少见,在遇到一些坑之后,解决了问题,先上坑: HOUR ...

  2. mysql查询删除重复记录查询_mysql怎么查询和删除重复记录

    查找所有重复标题的记录: SELECT * FROM t_info a WHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) > ...

  3. mysql 删除重复数据 保留一个_MySQL学习笔记-删除重复数据只保留一条

    有这样一张表,表数据及结果如下: 可以看出,school_name的字段值有重复数据(Abraham Lincoln High School 和Agoura High School分别出现两次),那么 ...

  4. mysql必学十大必会_MYSQL 学习(一)--启蒙篇《MYSQL必知必会》

    MYSQL必知必会 一. DDL 数据定义语言 Data Definition Language 是指CREATE,ALTER和DROP语句. DDL允许添加/修改/删除包含数据的逻辑结构,或允许用户 ...

  5. MySQL中引入存储引擎意义是_mysql学习九:存储引擎、存储过程和函数的引入

    存储引擎: 存储引擎是mysql特有的,共有7种,常用的有myisam.memory.innodb 查看表的存储引擎: show create table 表名; 修改表的存储引擎: alter ta ...

  6. MySQL8单表记录多少_mysql学习笔记之8(单表数据记录查询)_mysql

    mysql学习笔记之八(单表数据记录查询) 查询数据记录,就是指从数据库对象中获取所要求的数据记录.mysql中提供了各种不同方式的数据查询方法. 一.简单数据记录查询 select field1,f ...

  7. mysql查看比较大的数据表_mysql 如何查看哪些表数据量比较大

    数据库中有几十上百张表,那么哪些表的数据量比较大呢,总不能一个表一个表的去查询吧,在mysql中也有类似于oracle的数据字典表,只不过mysql没有oracle记录的那么多和详细,但也足够我们查询 ...

  8. mysql中更新的命令是_MySQL 语言中,更新表数据的命令是( )。_学小易找答案

    [简答题]MySQL 语言中包含数都定义语言.数据操纵语言和数据控制语言,分别有哪些功能? [单选题]查询员工工资信息时,结果按工资降序排列,正确的是( ). [简答题]arrayList测验 [填空 ...

  9. mysql 视图删除单条记录_从视图中删除行会从MySQL的基表中删除行吗?

    是的,从视图中删除行从基表中删除行.让我们通过创建一个新表来了解这一点.创建表的查询如下mysql> create table deleteFromBaseTableDemo -> ( - ...

  10. mysql中如何删除多个表格_mysql怎么批量删除多个表?

    mysql批量删除多个表的方法:使用"DROP TABLE"语句,只要将表名依次写在后面,相互之间用逗号隔开即可:语法格式"DROP TABLE [IF EXISTS] ...

最新文章

  1. 上班第一天(5)--一个程序员的成长史(14)
  2. ORACLE 查询日志
  3. linux 下使用 curl 访问带多参数,GET掉参数解决方案
  4. hibernate主键详细介绍
  5. 在内网服务器中获得真正的客户端ip的方法
  6. SpringMVC+Spring+mybatis
  7. java内存高水位_jvm(1)---java内存结构
  8. linux中yum教程,CentOS7下yum使用
  9. c#数据库訪问返回值类型为SqlDataReader时使用using时注意的问题
  10. linux 逻辑卷 pe size 4.00 mib大小怎么改,linux逻辑卷的建立
  11. 爱前端2018全栈大前端_启动2018年前端工具调查
  12. 寒冬之下,移动开发没人要了, iOS 开发者该 何去何从?
  13. 4.c++模式设计-建造者模式
  14. 用户注册PHP,PHP制作用户注册系统,php制作用户注册_PHP教程
  15. Python基础知识 D9
  16. 云数据库和本地数据库有什么区别?
  17. 金融计量模型(一):引言
  18. c#语言絢止函数是,取汉子拼音首字母的C#和VB.Net方法
  19. WPF—TimeLine类
  20. chrome浏览器主页被劫持为hao123

热门文章

  1. 蓝桥杯2016年第七届JavaC组国赛第一题-平方末尾
  2. Java 实现线程的两种方式
  3. Kotlin — 使用Eclipse运行第一个Kotlin程序,打印“Hello World”!
  4. Android setOnPageChangeListener 过时解决
  5. 微软发布下一代VS 2010和Framework 4.0
  6. [HDU2294]Pendant
  7. CCF-201703-1 分蛋糕
  8. img标签过滤加fs模块实现图片文件缓存
  9. Swift - 通过url地址打开web页面
  10. 吴昊品命令行解释程序 Round 2 —— 一个带括号的四则运算表达式的解释器(逆波兰式RPN)...