大家好,我是粥,昨天我们介绍了MySQL的索引模型。文末留下了一个疑问,为什么我们执行delete命令删除数据时,表数据文件的大小没有变化。这也是我之前面试遇到的问题。今天就和大家分享一下具体的原因。一般来说,如果我们要删除整个change,我们会直接使用droptable来回收表空间,但这是建立在我们以后不会再使用这张表的基础上的。但是在我们的业务开发中,遇到了很久的就是使用delete来删除具体的业务数据行。InnoDB在处理删除时会将空间地址标记为已删除,但不会真正删除。因为可以重用这个位置,所以磁盘文件的大小不会减少。比如昨天文章提到的例子,我转贴图给大家看一下,删除T4记录后,如果插入一行ID为5的行,就可以直接复用这块空间,不需要重新分配储存空间。但是如果插入了ID为8的行,这个位置就不能被复用了。如果删除单条记录,则这条单条记录的空间可以重新使用。再者,如果我们用delete命令删除整张表的数据呢?结果,所有数据页都被标记为可重用。但是在磁盘上,数据文件并没有响应lessstrain,因为它申请的表空间只是标记为重用,并没有真正回收。由此我们可以得出结论,删除命令实际上只是将记录或数据页的位置标记为“可重用”,而磁盘文件的大小并不会改变。也就是说,表空间不能被delete命令回收。这些可以重复使用,但未使用的空间看起来像“空的”。其实不仅是删除数据会产生空洞,插入数据也会产生空洞。如果数据以索引递增的顺序插入,则索引是紧凑的。但是,如果随机插入数据,可能会导致索引的数据页分裂。一般来说,经过大量增删改查的表,都可能存在漏洞。因此,如果能把这些洞去掉,就可以达到缩小表空间的目的。而重建表可以达到这个目的。这里可以使用altertabletestengine=InnoDB命令重建表。在MySQL5.5之前,MySQL会自动完成转储数据、交换表名、删除旧表等操作。显然,耗时最多的步骤就是向临时表插入数据的过程。如果在这个过程中有新的数据要写入A表,就会丢失数据。所以在整个DDL过程中,表test不能有更新。也就是说,这个DDL是不Online的。MySQL5.6引入的OnlineDDL优化了这个操作过程。引入OnlineDDL后,重建表的过程创建一个临时文件,扫描表test的主键的所有数据页;将数据页中A表的记录生成B+树,存入临时文件;在生成临时文件的过程中,将所有对test的操作记录在一个日志文件(rowlog)中;生成临时文件后,将日志文件中的操作应用到临时文件中,得到与表test逻辑数据相同的数据文件;将其替换为表测试的临时文件数据文件。由于DDLOnline存在日志文件记录和重放操作的功能,该方案允许在重建表的过程中对表test进行增删改操作,这就是OnlineDDL名称的来源.通过重建表,我们实际上可以回收表空间。综上所述,今天我们主要分享了delete删除数据时表中数据文件大小没有变化的原因。主要原因是InnoDB引擎在处理删除数据时,将删除行的位置标记为可用。复用,不是真正的删除,所以会出现这种数据被删除但是表文件大小没有变化的情况。好了,我们今天的内容就到此结束。这两天我们分享了什么是指数模型。从明天开始,我将分享如何在MySQL中使用索引。我是程序员,稀饭,关注我,我们一起在技术的海洋中向上成长。
